Exemple #1
0
def espresso_tts(*tts):
    """Return a tuple of expressions optimized using Espresso."""
    for f in tts:
        if not isinstance(f, TruthTable):
            raise ValueError("expected a TruthTable instance")

    support = frozenset.union(*[f.support for f in tts])
    inputs = sorted(support)

    ninputs = len(inputs)
    noutputs = len(tts)

    cover = set()
    for i, point in enumerate(boolfunc.iter_points(inputs)):
        invec = [2 if point[v] else 1 for v in inputs]
        outvec = list()
        for f in tts:
            val = f.pcdata[i]
            if val == PC_ZERO:
                outvec.append(0)
            elif val == PC_ONE:
                outvec.append(1)
            elif val == PC_DC:
                outvec.append(2)
            else:
                raise ValueError("expected truth table entry in {0, 1, -}")
        cover.add((tuple(invec), tuple(outvec)))

    set_config(**CONFIG)

    cover = espresso(ninputs, noutputs, cover, intype=FTYPE|DTYPE|RTYPE)
    inputs = [exprvar(v.names, v.indices) for v in inputs]
    return _cover2exprs(inputs, noutputs, cover)
Exemple #2
0
 def items():
     """Iterate through AND'ed items."""
     for point in boolfunc.iter_points(inputs):
         # pylint: disable=C0103
         ab = self.restrict(point).pcdata[0]
         cd = other.restrict(point).pcdata[0]
         # a & c, b | d
         yield ((ab & cd) & 2) | ((ab | cd) & 1)
Exemple #3
0
 def items():
     """Iterate through AND'ed items."""
     for point in boolfunc.iter_points(inputs):
         # pylint: disable=C0103
         ab = self.restrict(point).pcdata[0]
         cd = other.restrict(point).pcdata[0]
         # a & c, b | d
         yield ((ab & cd) & 2) | ((ab | cd) & 1)
Exemple #4
0
 def items():
     """Iterate through XOR'ed items."""
     for point in boolfunc.iter_points(inputs):
         # pylint: disable=C0103
         ab = self.restrict(point).pcdata[0]
         cd = other.restrict(point).pcdata[0]
         # a & d | b & c, a & c | b & d
         a, b, c, d = ab >> 1, ab & 1, cd >> 1, cd & 1
         yield ((a & d | b & c) << 1) | (a & c | b & d)
Exemple #5
0
 def items():
     """Iterate through XOR'ed items."""
     for point in boolfunc.iter_points(inputs):
         # pylint: disable=C0103
         ab = self.restrict(point).pcdata[0]
         cd = other.restrict(point).pcdata[0]
         # a & d | b & c, a & c | b & d
         a, b, c, d = ab >> 1, ab & 1, cd >> 1, cd & 1
         yield ((a & d | b & c) << 1) | (a & c | b & d)
Exemple #6
0
 def items():
     """Iterate through composed outputs."""
     for point in boolfunc.iter_points(inputs):
         gpnt = {v: val for v, val in point.items()
                 if v not in unmapped}
         gval = gfunc.restrict(gpnt)
         # mapped function must be completely specified
         assert isinstance(gval, TTConstant)
         fpnt = {v: val for v, val in point.items()
                 if v in unmapped}
         fpnt[gvar] = int(gval)
         yield func.restrict(fpnt).pcdata[0]
Exemple #7
0
def preprocess_cuts(cuts):
	"""!
	"""
	## optimised cuts dictionary with removed control wires
	cuts_opt = {}
	for node in sorted(cuts.keys()):

		# if node is not a input or output
		if not node.startswith("INPUT"):
			# nodes without a cut are not included in the optimised cuts
			if cuts[node] == 'n.a.':
				pass
			else:
				cuts_opt[node] = []
				# for each single cut, which is not first trivial cut, or a cut of only x inputs (as this represents general functions like NAND, XNOR etc, and allows for way to many matches - these are found with structural shape hashing)
				for singleCut in cuts[node][1:]:
					#todo: make this value inputtable
					if len(singleCut.inputs) > 3:

						# find if cut contains a control wire,
						wireList = []
						for wire in func.control_wires:
							wire = exprvar(wire)
							if wire in singleCut.inputs:
								wireList.append(wire)

						# if wire list is empty, no control wires are contained within cut, cut is written to optimised cuts as is
						if not wireList:
							cuts_opt[node].append([singleCut, {}])


						# if wirelist is not empty, cut contains a control wire, several optimised cuts are written to optimised cuts dictionary
						else:
							counter = 0
							for cofactor in singleCut.cofactors(sorted(wireList)):
								if str(cofactor) != "1" and str(cofactor) != "0":

									truthTable = list(boolfunc.iter_points(wireList))
									permut = truthTable[counter]
									if [cofactor, permut] not in cuts_opt[node] and [cofactor, {}] not in cuts_opt[node]:
										cuts_opt[node].append([cofactor, permut])
								counter = counter +1




	# fixme: some cuts are still in twice after cofactoring - problem with pyeda expressions


	# cuts_opt = {nodeName : [[cut1 , {perm}], [cuts2, {perm2}]...]}
	return cuts_opt
Exemple #8
0
def test_iter_points():
    assert list(iter_points([a, b])) == [{
        a: 0,
        b: 0
    }, {
        a: 1,
        b: 0
    }, {
        a: 0,
        b: 1
    }, {
        a: 1,
        b: 1
    }]
Exemple #9
0
def espresso_tts(*tts):
    """Return a tuple of expressions optimized using Espresso.

    The variadic *tts* argument is a sequence of truth tables.

    For example::

       >>> from pyeda.boolalg.bfarray import exprvars
       >>> from pyeda.boolalg.table import truthtable
       >>> X = exprvars('x', 4)
       >>> f1 = truthtable(X, "0000011111------")
       >>> f2 = truthtable(X, "0001111100------")
       >>> f1m, f2m = espresso_tts(f1, f2)
       >>> f1m.equivalent(X[3] | X[0] & X[2] | X[1] & X[2])
       True
       >>> f2m.equivalent(X[2] | X[0] & X[1])
       True
    """
    for f in tts:
        if not isinstance(f, TruthTable):
            raise ValueError("expected a TruthTable instance")

    support = frozenset.union(*[f.support for f in tts])
    inputs = sorted(support)

    ninputs = len(inputs)
    noutputs = len(tts)

    cover = set()
    for i, point in enumerate(boolfunc.iter_points(inputs)):
        invec = [2 if point[v] else 1 for v in inputs]
        outvec = list()
        for f in tts:
            val = f.pcdata[i]
            if val == PC_ZERO:
                outvec.append(0)
            elif val == PC_ONE:
                outvec.append(1)
            elif val == PC_DC:
                outvec.append(2)
            else:
                raise ValueError("expected truth table entry in {0, 1, -}")
        cover.add((tuple(invec), tuple(outvec)))

    set_config(**CONFIG)

    cover = espresso(ninputs, noutputs, cover, intype=FTYPE|DTYPE|RTYPE)
    inputs = [exprvar(v.names, v.indices) for v in inputs]
    return _cover2exprs(inputs, noutputs, cover)
Exemple #10
0
def espresso_tts(*tts):
    """Return a tuple of expressions optimized using Espresso.

    The variadic *tts* argument is a sequence of truth tables.

    For example::

       >>> from pyeda.boolalg.bfarray import exprvars
       >>> from pyeda.boolalg.table import truthtable
       >>> X = exprvars('x', 4)
       >>> f1 = truthtable(X, "0000011111------")
       >>> f2 = truthtable(X, "0001111100------")
       >>> f1m, f2m = espresso_tts(f1, f2)
       >>> f1m.equivalent(X[3] | X[0] & X[2] | X[1] & X[2])
       True
       >>> f2m.equivalent(X[2] | X[0] & X[1])
       True
    """
    for f in tts:
        if not isinstance(f, TruthTable):
            raise ValueError("expected a TruthTable instance")

    support = frozenset.union(*[f.support for f in tts])
    inputs = sorted(support)

    ninputs = len(inputs)
    noutputs = len(tts)

    cover = set()
    for i, point in enumerate(boolfunc.iter_points(inputs)):
        invec = [2 if point[v] else 1 for v in inputs]
        outvec = list()
        for f in tts:
            val = f.pcdata[i]
            if val == PC_ZERO:
                outvec.append(0)
            elif val == PC_ONE:
                outvec.append(1)
            elif val == PC_DC:
                outvec.append(2)
            else:
                raise ValueError("expected truth table entry in {0, 1, -}")
        cover.add((tuple(invec), tuple(outvec)))

    set_config(**CONFIG)

    cover = espresso(ninputs, noutputs, cover, intype=FTYPE | DTYPE | RTYPE)
    inputs = [exprvar(v.names, v.indices) for v in inputs]
    return _cover2exprs(inputs, noutputs, cover)
Exemple #11
0
 def expand(self, vs=None, conj=False):
     """Return the Shannon expansion with respect to a list of variables."""
     vs = self._expect_vars(vs)
     if vs:
         outer, inner = (And, Or) if conj else (Or, And)
         terms = [inner(self.restrict(p),
                        *boolfunc.point2term(p, conj))
                  for p in boolfunc.iter_points(vs)]
         if conj:
             terms = [term for term in terms if term is not One]
         else:
             terms = [term for term in terms if term is not Zero]
         return outer(*terms, simplify=False)
     else:
         return self
Exemple #12
0
 def expand(self, vs=None, conj=False):
     """Return the Shannon expansion with respect to a list of variables."""
     vs = self._expect_vars(vs)
     if vs:
         outer, inner = (And, Or) if conj else (Or, And)
         terms = [inner(self.restrict(p),
                        *boolfunc.point2term(p, conj))
                  for p in boolfunc.iter_points(vs)]
         if conj:
             terms = [term for term in terms if term is not One]
         else:
             terms = [term for term in terms if term is not Zero]
         return outer(*terms, simplify=False)
     else:
         return self
Exemple #13
0
def calc_prep(cut, P, PVarList):
	"""!
	Function calculates representative function for given cut

	Function converts truthtable outvector to smallest p-representative using permutation trees . runtime = O(|V|+|E|) reduced due to using only smallest path in search tree
	@param [in] cut as pyeda formula
	@param [in] P as DiGraph of permutation tree of size (len(cut.inputs))

	@param [out] pRep as list containg the p-representative
	"""
	# create truthtable of cut
	T = expr2truthtable(cut)
	inputs = T.inputs

	# calculate the outvector of the truth table of cut
	outvec = list()

	for i, point in enumerate(boolfunc.iter_points(inputs)):
		#~ invec = [2 if point[v] else 1 for v in inputs]
		val = T.pcdata[i]
		if val == PC_ZERO:
			outvec.append(0)
		elif val == PC_ONE:
			outvec.append(1)
		elif val == PC_DC:
			outvec.append(2)

	# search permutation tree, to find smallest pRepresentative
	coefPerm = search_permut_tree(P, [nx.topological_sort(P)[0]], outvec)

	coefPerm = coefPerm.split("_")[1:]

	# find pRep from coefficent permutation and outvector of truth table
	pRep = []
	for i in range(len(outvec)):
		pRep.append(outvec[int(coefPerm[i])])

	for x in range(len(coefPerm)):
		coefPerm[x] = int(coefPerm[x])

	permDict = PVarList["perm" + str(int(math.log(len(coefPerm))/math.log(2)))]
	permut = permDict[str(coefPerm)]

	return pRep, permut
Exemple #14
0
def test_iter_points():
    assert list(iter_points([a, b])) == [{a: 0, b: 0}, {a: 1, b: 0}, {a: 0, b: 1}, {a: 1, b: 1}]