示例#1
0
        def add_element_to_tuples(tuples_set, new_element):
            """
            Adds additional element to a tuple set.
            :param tuples_set: a set containing tuples.
            :param new_element: any element to add in last position.
            :return: tuple set
            """
            new_tuples = LastUpdateSet()
            for tuple_element in tuples_set:
                new_tuples.add(tuple_element + (new_element,))

            return new_tuples
    def test_order(self):

        """Check that order is preserved."""

        s = LastUpdateSet()

        old_list = ['4', '3', '2', '1', '5']

        for e in old_list:
            s.add(e)

        new_list = []
        for e in s:
            new_list.append(e)

        self.assertEqual(new_list, old_list)
示例#3
0
    def __get_prime_implicants(self, terms):
        """Simplify the set 'terms'.

        Args:
            terms (set of str): set of strings representing the minterms of
            ones and dontcares.

        Returns:
            A list of prime implicants. These are the minterms that cannot be
            reduced with step 1 of the Quine McCluskey method.

        This is the very first step in the Quine McCluskey algorithm. This
        generates all prime implicants, whether they are redundant or not.
        """

        # Sort and remove duplicates.
        n_groups = self.n_bits + 1
        marked = LastUpdateSet()

        # Group terms into the list groups.
        # groups is a list of length n_groups.
        # Each element of groups is a set of terms with the same number
        # of ones.  In other words, each term contained in the set
        # groups[i] contains exactly i ones.
        groups = [LastUpdateSet() for i in range(n_groups)]
        for t in terms:
            n_bits = t.count('1')
            groups[n_bits].add(t)
        if self.use_xor:
            # Add 'simple' XOR and XNOR terms to the set of terms.
            # Simple means the terms can be obtained by combining just two
            # bits.
            for gi, group in enumerate(groups):
                for t1 in group:
                    for t2 in group:
                        t12 = self.__reduce_simple_xor_terms(t1, t2)
                        if t12 != None:
                            terms.add(t12)
                    if gi < n_groups - 2:
                        for t2 in groups[gi + 2]:
                            t12 = self.__reduce_simple_xnor_terms(t1, t2)
                            if t12 != None:
                                terms.add(t12)

        done = False
        while not done:
            # Group terms into groups.
            # groups is a list of length n_groups.
            # Each element of groups is a set of terms with the same
            # number of ones.  In other words, each term contained in the
            # set groups[i] contains exactly i ones.
            groups = dict()
            for t in terms:
                n_ones = t.count('1')
                n_xor  = t.count('^')
                n_xnor = t.count('~')
                # The algorithm can not cope with mixed XORs and XNORs in
                # one expression.
                assert n_xor == 0 or n_xnor == 0

                key = (n_ones, n_xor, n_xnor)
                if key not in groups:
                    groups[key] = LastUpdateSet()
                groups[key].add(t)

            terms = LastUpdateSet()           # The set of new created terms
            used = LastUpdateSet()            # The set of used terms

            # Find prime implicants
            for key in groups:
                key_next = (key[0]+1, key[1], key[2])
                if key_next in groups:
                    group_next = groups[key_next]
                    for t1 in groups[key]:
                        # Optimisation:
                        # The Quine-McCluskey algorithm compares t1 with
                        # each element of the next group. (Normal approach)
                        # But in reality it is faster to construct all
                        # possible permutations of t1 by adding a '1' in
                        # opportune positions and check if this new term is
                        # contained in the set groups[key_next].
                        for i, c1 in enumerate(t1):
                            if c1 == '0':
                                self.profile_cmp += 1
                                t2 = t1[:i] + '1' + t1[i+1:]
                                if t2 in group_next:
                                    t12 = t1[:i] + '-' + t1[i+1:]
                                    used.add(t1)
                                    used.add(t2)
                                    terms.add(t12)

            # Find XOR combinations
            for key in [k for k in groups if k[1] > 0]:
                key_complement = (key[0] + 1, key[2], key[1])
                if key_complement in groups:
                    for t1 in groups[key]:
                        t1_complement = t1.replace('^', '~')
                        for i, c1 in enumerate(t1):
                            if c1 == '0':
                                self.profile_xor += 1
                                t2 = t1_complement[:i] + '1' + t1_complement[i+1:]
                                if t2 in groups[key_complement]:
                                    t12 = t1[:i] + '^' + t1[i+1:]
                                    used.add(t1)
                                    terms.add(t12)
            # Find XNOR combinations
            for key in [k for k in groups if k[2] > 0]:
                key_complement = (key[0] + 1, key[2], key[1])
                if key_complement in groups:
                    for t1 in groups[key]:
                        t1_complement = t1.replace('~', '^')
                        for i, c1 in enumerate(t1):
                            if c1 == '0':
                                self.profile_xnor += 1
                                t2 = t1_complement[:i] + '1' + t1_complement[i+1:]
                                if t2 in groups[key_complement]:
                                    t12 = t1[:i] + '~' + t1[i+1:]
                                    used.add(t1)
                                    terms.add(t12)

            # Add the unused terms to the list of marked terms
            for g in list(groups.values()):
                marked |= g - used

            if len(used) == 0:
                done = True

        # Prepare the list of prime implicants
        pi = marked
        for g in list(groups.values()):
            pi |= g
        return pi