View Single Post
Old Jun 2nd, 2006, 10:54 PM   #6
Sane
Programming Guru
 
Sane's Avatar
 
Join Date: Apr 2005
Location: Waterloo, Ontario
Posts: 2,013
Rep Power: 6 Sane will become famous soon enough
Send a message via MSN to Sane
I assume if you don't know enough to understand my issue and proposed solution, then you don't know enough to help me. I explained to a reasonable extent what needs to be accomplished, and I'm asking you what you think should be done "step by step".

I've developed a good chunk of framework for this program, let me know if you think I'm doing anything wrong. This is in Python.

What it does is starts with the smallest number of columns in the input side to try to minimilize the inputs that the logical expression uses. If this column does not satisfy enough unique inputs to outputs, then it proceeds to the next combination of column(s). When it finds a combination that does not have more then one output for the same input, validate() returns true and outputs the corresponding column of bits.

If you run this program, you can see that for the "or" truth table, that the smallest number of columns possible to achieve a "validated" possibility of succeeding a logical expression, is both columns combined. This can be used to limit the possibilities, and also catch any obvious methods straight off the bat.

IN SHORT... it tells you what input columns could (and should) be used to determine the "_output'th" output column, in order from smallest to greatest number of bits.

Feel free to add and/or modify accordingly.

class keep_index:
    """custom integer that can be called for its index value,
    easiest way to attach a static value to a dynamic value"""
    def __init__(self, value, index):
        self.value = str(value)
        self.index = index
        
    def __call__(self):
        return self.index
    
    def __repr__(self):
        return self.value

    def __lt__(self, other):
        return self.value < other

    def __le__(self, other):
        return self.value <= other

    def __eq__(self, other):
        return self.value == other

    def __ne__(self, other):
        return self.value != other

    def __gt__(self, other):
        return self.value > other

    def __ge__(self, other):
        return self.value >= other        

def index_table(table):
    """add the index of each item in the table"""
    ntable = []
    for row in table:
        ntable += [[[]]]
        for i, item in enumerate(row[0]):
            ntable[-1][-1].append(keep_index(item, i))
        ntable[-1].append(row[1])
    return ntable

def comb_list(seq, k):
    """    Algorithm by Gilward Kukel
    http://www.programmingforums.org/forum/showthread.php?t=4343

    returns a list of all k-combinations
    of the elements of sequence seq"""
    
    n=len(seq)
    if not 0<=k<=n:
        raise Exception,"0<=k<=len(seq) is not true"
    v=[]   #list of combinations
    #x: number of taken elements
    #y: number of rejected elements
    #we want to take k elements and reject n-k elements
    def f(x,y,a):
        if x==k:
            #we have taken enough elements, reject all remaining elements
            v.append(a)
            return
        if y==n-k:
            #we have rejected enough elements, take all remaining elements
            a.extend(seq[x+y:])
            v.append(a)
            return
        if (x<k):
            #take element seq[x+y]
            h=a+[seq[x+y]]
            f(x+1,y,h)
        if (y<n-k):
            #don't take element seq[x+y]
            f(x,y+1,a)            
    f(0,0,[])
    return v

def fetch(table, b):
    """fetch a column from the table"""
    '''
    [
    [[(0, 0), (0, 1)], [(0, 0), (2, 2)], [(0, 1), (2, 2)]],
    [[(0, 0), (1, 1)], [(0, 0), (2, 2)], [(1, 1), (2, 2)]],
    [[(1, 0), (0, 1)], [(1, 0), (2, 2)], [(0, 1), (2, 2)]],
    [[(1, 0), (1, 1)], [(1, 0), (2, 2)], [(1, 1), (2, 2)]]
    ]
    '''
    t = []
    for row in table:
        t.append([])
        for item in row[b]:
            t[-1].append(item)
    
    return t

def validate(col, out):
    """find out if a logical expression is possible for this
    column(s) (if there are two results for the same input)"""
    '''
    [[0, 0], [0, 1], [1, 0], [1, 1]], [0, 1, 1, 1]
    '''
    for find, flp in enumerate(col):
        for sind, slp in enumerate(col):
            if flp == slp and find != sind:
                if out[find] != out[sind]:
                    return False
    return True

def main(table):
    INPUTS  = len(table[0][0])
    OUTPUTS = len(table[0][1])
    ntable = index_table(table)

    # figure out each output column one by one
    for _output in range(OUTPUTS):

        # grab the output column from the table
        out = [row[1][_output] for row in ntable]

        # we can't go past "INPUT" number of columns in the expression
        for _input in range(1, INPUTS+1):
            
            choices = []
            
            for row in ntable:
                # get all combination of elements inside a
                # row that is _input'th elements long
                choices += [comb_list(row[0], _input)]

            for choice in range(len(choices[0])):
                # fetch the column of each combination
                columns = fetch(choices, choice)

                # validate it with the "vertical line test"
                if validate(columns, out):
                    print columns

if __name__ == '__main__':
    table = [[[0, 0], [0]],
             [[0, 1], [1]],
             [[1, 0], [1]],
             [[1, 1], [1]]]
    main(table)

Last edited by Sane; Jun 2nd, 2006 at 11:21 PM.
Sane is offline   Reply With Quote