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)
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