number of arguments a function takes

Corey Coughlin corey.coughlin at attbi.com
Fri Jan 30 23:26:15 CET 2004


OK, here's my object.  Basically, you set up a truth table with the
input and output pins, then you can add values to it usings
dictionaries of the form { 'pin name': 0 or 1......} to represent each
state.  The point here is more to deduce the boolean functions of a
table from data observed from black box boolean functions, very useful
for my job in semiconductors.  Keep in mind that I wasn't exactly
trained in software, so my code is usually a little rough and brute
force, which keeps it from being less elegant, but easy to understand.
 Anyway, if you have any questions, feel free to ask.

class TruthTable(object):
    def __init__(self,iinputs= [], ioutputs=[]):
        self.ttab = {}
        self.inpindex = {}
        self.vcount = 0
        if iinputs and ioutputs:
            self.vcount = 2 ** len(iinputs)
            i = 1
            for input in iinputs:
                self.inpindex[input] = i
                i = i * 2
            for output in ioutputs:
                self.ttab[output] = [ None ] * self.vcount
    def reducetable(self):
        newinputs = []
        onegone = False
        for ipin in self.inpindex.keys():
            iused = False
            for opin in self.ttab.keys():
                iused = iused or self.findtransitions(ipin, opin)
            if iused:
                newinputs.append(ipin)
            else:
                onegone = True
        if not onegone:
            return None
        i = 1
        newindex = {}
        newttab = {}
        newcount = 2 ** len(newinputs)
        for ipin in newinputs:
            newindex[ipin] = i
            i = i * 2
        for opin in self.ttab.keys():
            newttab[opin] = [None] * newcount
        for i in range(newcount):
            curristate = {}
            for ipin, bplace in newindex.items():
                curristate[ipin] = ( i & bplace ) / bplace
            for j in range(self.vcount):
                oldstate = self.vec2output(j)
                matched = True
                for ipin in curristate:
                    matched = matched and curristate[ipin] ==
oldstate[ipin]
                if matched:
                    for opin in newttab:
                        newttab[opin][i] = oldstate[opin]
        self.ttab = newttab
        self.inpindex = newindex
        self.vcount = newcount
    def addvalues(self, ttentry):
        index = 0
        foundall = True
        for ipin in self.inpindex:
            if ipin not in ttentry:
                raise KeyError, 'Pin %s not in %s' % (ipin, ttentry)
            else:
                index = index + ttentry[ipin] * self.inpindex[ipin]
        for pin, value in ttentry.items():
            if pin in self.ttab:
                self.ttab[pin][index] = value
    def deloutput(self, outname):
        if self.ttab.has_key(outname):
            del self.ttab[outname]
    def vec2output(self, vec):
        outent = {}
        for input, binplace in self.inpindex.items():
            outent[input] = ( vec & binplace) / binplace
        for output, outvals in self.ttab.items():
            outent[output] = outvals[vec]
        return outent
    def getvalue(self, inpstate, opin):
        if opin not in self.ttab:
            raise IndexError, 'Incorrect output pin %s used in
getvalue.' % opin
        stindex = 0
        for ipin in self.inpindex:
            if ipin not in inpstate:
                raise KeyError, 'Pin %s cannot be found in inpstate
%s' % (ipin, inpstate)
            stindex = stindex + self.inpindex[ipin] * inpstate[ipin]
        return self.ttab[opin][stindex]
    def __str__(self):
        outs = ''
        allpins = self.inpindex.keys() + self.ttab.keys()
        maxname = 0
        for pin in allpins:
            if len(pin) > maxname:
                maxname = len(pin)
        if maxname < 5:
            maxname = 5
        indicies = self.inpindex.values()
        indicies.sort()
        indicies.reverse()
        indtoinp = {}
        inputs = []
        for input, index in self.inpindex.items():
            indtoinp[index] = input
        for i in indicies:
            outs = outs + '%s ' % stringfill(indtoinp[i], maxname)
            inputs.append(indtoinp[i])
        outs = outs + '| '
        outputs = self.ttab.keys()
        outputs.sort()
        for out in outputs:
            outs = outs + '%s ' % stringfill(out, maxname)
        outs = outs + '\n'
        for i in range(self.vcount):
            currvec = self.vec2output(i)
            for inp in inputs:
                outs = outs + '%s ' % stringfill(str(currvec[inp]),
maxname)
            outs = outs + '| '
            for out in outputs:
                outs = outs + '%s ' % stringfill(str(currvec[out]),
maxname)
            outs = outs + '\n'
        return outs
    def findtransitions(self, ipin, opin):
        indicies = range(self.vcount)
        binplace = self.inpindex[ipin]
        zerobits = filter(lambda x: x & binplace == 0, indicies)
        possibles = map(lambda x: ( x, x + binplace ), zerobits)
        foundtrans = []
        for lowbit, highbit in possibles:
            ovec = self.ttab[opin]
            if (ovec[lowbit] != ovec[highbit] and ovec[lowbit] in
[0,1] and
                ovec[highbit] in [0,1]):
                foundtrans.append( (lowbit, highbit) )
        foundtrans = map(lambda x: ( self.vec2output(x[0]),
                         self.vec2output(x[1]) ),
                         foundtrans)
        return foundtrans
    def getoutfunc2(self, opin, notxwhens = []):
        if opin not in self.ttab:
            return '',''
        relpins = []
        for ipin in self.inpindex.keys():
            tranpairs = self.alltransitions(ipin)
            for lowst, highst in tranpairs:
                if lowst[opin] != highst[opin] and ipin not in
relpins:
                    relpins.append(ipin)
        if relpins == []:
            return '',''
        outhighs = []
        outx = []
        allone = True
        for vec in range(self.vcount):
            pvec = self.vec2output(vec)
            if pvec[opin] in  [1, 'X']:
                saveout = pvec[opin]
                for pin in pvec.keys():
                    a = pin in self.ttab
                    b = pin not in relpins
                    if a or b:
                        del pvec[pin]
                if len(pvec) > 0:
                    allone = False
                if saveout == 1 and pvec not in outhighs:
                    outhighs.append(pvec)
                if saveout == 'X' and pvec not in outx:
                    outx.append(pvec)
        outfunc = ''
        xfunc = ''
        if allone:
            return '1',''
        for cwhen in outhighs:
            pstring = WhenString(cwhen)
            if outfunc == '':
                outfunc = '(%s)' % pstring
            else:
                outfunc = '%s|(%s)' % (outfunc, pstring)
        if notxwhens:
            print 'finding badxwhens'
            badxwhens = []
            for cwhen in outx:
                for subwhen in notxwhens:
                    if DictIn(cwhen,subwhen):
                        badxwhens.append(cwhen)
                        break
            for bwhen in badxwhens:
                outx.remove(bwhen)
        for cwhen in outx:
            pstring = WhenString(cwhen)
            if xfunc == '':
                xfunc = '(%s)' % pstring
            else:
                xfunc = '%s|(%s)' % (xfunc, pstring)
        return outfunc, xfunc
    def alltransitions(self, ipin):
        indicies = range(self.vcount)
        binplace = self.inpindex[ipin]
        zerobits = filter(lambda x: x & binplace == 0, indicies)
        possibles = map(lambda x: ( x, x + binplace ), zerobits)
        foundtrans = []
        foundtrans = map(lambda x: ( self.vec2output(x[0]), 
                         self.vec2output(x[1]) ),
                         possibles)
        return foundtrans
    def getinputs(self):
        return self.inpindex.keys()
    def getoutputs(self):
        return self.ttab.keys()
    def __len__(self):
        return self.vcount

Oh, and a function called WhenString is also called, here's that:

def WhenString(statein):
    pstring = ''
    pinlist = statein.keys()
    pinlist.sort()
    for pin in pinlist:
        if pstring != '':           
            pstring = '%s&' % pstring
        if statein[pin] == 0:
            pstring = '%s!' % pstring
        if statein[pin] in [0, 1]:
            pstring = '%s%s' % (pstring, pin)
    if pstring and pstring[-1] in ['&', '!']:
        pstring = pstring[:-1]
    return pstring

I took out some comments and a couple of differential specific
functions to clear things up, and it's a little cluttered up with code
to check for 'X' states, but that's it.  Let me know what you think. 
:)



More information about the Python-list mailing list