Example #1
0
        def __init__(self, state_word_len, variables):
            """ Initialize the internal helper class. """

            self.state_word_len = state_word_len
            self.variables = variables
            variable_names = map(lambda i: 'S%d' % i,
                                 xrange(self.state_word_len))
            variable_names += self.variables
            self.qm = qm.QM(variable_names)
Example #2
0
def main():
  n = 3
  qm1 = qm.QM([chr(code) for code in xrange(ord('A'),ord('A')+n)])

  for minterms in itertools.chain(*(itertools.combinations(range(1<<n),i) for i in xrange(1,1<<n+1))):
    minterms = set(minterms)
    if max(minterms) == 0:
      continue
    for dc in itertools.chain(*(itertools.combinations(minterms,i) for i in xrange(0,len(minterms)+1))):
      dc = list(dc)
      ones = list(minterms - set(dc))
      check = qm1.solve(ones,dc)
      correct = qm_orig.qm(ones=ones,dc=dc)
      if not eq(check, correct, dc):
        print 'ERROR',ones,dc,t(check, n),qm1.get_function(check[1]),correct,check
Example #3
0
def get_canonical_minimal_sop_from_string(boolean_string, boolean_variables):
    '''Returns the full minimal canonical form for all the variables
    passed, given the string, or simply '0' if the string always evaluates
    to False.
    
    >>> get_canonical_minimal_sop_from_string('A AND (B OR C)', ['A', 'B', 'C'])
    [(3, 4), (5, 2)]
    '''

    min_terms = get_minterms_from_string(boolean_string, boolean_variables)

    _qm = qm.QM(boolean_variables)

    minimal_sop = _qm.solve(min_terms, [])

    return minimal_sop[1]
Example #4
0
def Getfunc(inputlist,
            output,
            onlist,
            prefix='n',
            suffix='n',
            equal_sign='*='):
    '''
  Return a Boolean regulatory rule in the disjuctive normal form (in the format of Booleannet)
  based on given truth table.
  For more details about Booleannet, refer to https://github.com/ialbert/booleannet.
  It is essentially a wrapper for the Quine-McCluskey algorithm to meet the format of Booleannet.


  Parameters
  ----------
  inputlist : a list of nodenames of all the parent nodes/ regulators
  output    : the nodename of the child node
  onlist    : a list of all configurations(strings) that will give a ON state of the output based on rule
              e.g. the onlist of C = A OR B will be ['11','10','01']
  prefix='n': prefix to encode the node name to avoid one node's name is a part of another node's name
  suffix='n': suffix to encode the node name to avoid one node's name is a part of another node's name
              e.g. node name '1' will become 'n1n' in the returned result
  equal_sign: the equal sign of the rule in the returned result, whose default value follows the Booleannet format

  Returns
  -------
  The Boolean rule in the disjuctive normal form.


  References
  ----------
  QM code by George Prekas.
  '''
    #pre-processing to meet the format requirement of QM and Booleannet
    inputs = [prefix + str(x) + suffix for x in inputlist]
    inputs.reverse()
    output = prefix + str(output) + suffix + equal_sign
    onindexlist = [int(x, 2) for x in onlist]
    if len(inputs) > 0:
        qmtemp = qm.QM(inputs)
        temprule = qmtemp.get_function(qmtemp.solve(onindexlist, [])[1])
        temprule = temprule.replace('AND', 'and')
        temprule = temprule.replace('OR', 'or')
        temprule = temprule.replace('NOT', 'not')
    else:
        temprule = output[:-2]
    return output + temprule + '\n'
Example #5
0
def minimize(Equations):
    Max = {}
    for name in Equations:
        Max[name] = max(Equations[name])

    minimized = {}
    for name in sorted(Equations):
        minimized[name] = {}
        for value in Equations[name]:
            Eq = Equations[name][value]
            names = [name] + sorted(Eq.variables())
            if any([max(Equations[n]) > 1 for n in names]):
                minimized[name][value] = 'Non-Boolean'
                continue

            # sum notation for QM input
            names = sorted(Eq.variables())
            ones = []
            size = len(names)

            for i, y in enumerate(itertools.product(*size * [[0, 1]])):

                y = dict(zip(names, y))
                if Eq(y): ones.append(i)

            # run QM
            rev = names[:]
            rev.reverse()
            solver = qm.QM(rev)
            minterms = solver.compute_primes(ones)
            dcs = []
            f = solver.get_function(solver.solve(ones, dcs)[1])
            f = f.replace(' AND ', ' & ')
            f = f.replace(' OR ', ' | ')
            f = f.replace('NOT', '!')
            if f[0] == '(' and f[-1] == ')': f = f[1:-1]

            minimized[name][value] = f

    return minimized
Example #6
0
def _solve( Equation, Max, Minimize ):

    # one boolean variable for each threshold
    BooleanVariables = []
    for name in Equation.variables():
        for v in range(Max[name]+1): # for v in range(1,Max[name]+1):
            BooleanVariables.append( '%s=%i'%(name,v) )
    size = len(Equation.variables())

    # sum notation for QM input
    ones = []
    dcs  = []    
    for i,y in enumerate(itertools.product(*len(BooleanVariables)*[[0,1]])):
        y = zip(BooleanVariables,y)
        
        # boolean state to multi value state
        valid = True
        x = {}
        for atom, state in y:
            if state:
                name, value = atom.split('=')
                value = int(value)
            
                if name in x:
                    valid = False
                    break
                x[name] = value

        if not len(x)==size:
            valid=False

        if not valid:
            dcs.append(i)
            pass
        elif Equation(x):
            ones.append(i)

    # run QM
    rev = BooleanVariables[:]
    rev.reverse()
    solver = qm.QM( rev )
    minterms = solver.compute_primes(ones+dcs)

    if Minimize:
        minimized = solver.get_function(  solver.solve( ones,dcs )[1]  )
        minimized = minimized.replace(' AND ',' & ')
        minimized = minimized.replace(' OR ',' | ')
        minimized = minimized.replace('NOT','!')

        return minimized

    # convert minterms to primes
    primes = []
    
    for i,minterm in enumerate(minterms):
        print '---'

        options   = {} #dict([(name,range(Max[name]+1)) for name in Equation.variables()])
        valid = True
        m = []
        for j in xrange(len(rev)):
            name, value = rev[j].split('=')
            value = int(value)
            
            if minterm[0] & 1<<j:# non-negated literal
                #prime[rev[j]]=1
                m.append('%s==%i'%(name,value))
                if options.has_key(name):# invalid prime
                    if not value in options[name]:
                        print 'invalid 1'
                        valid=False
                options[name]=[value]
                
            elif not minterm[1] & 1<<j:# negated literal
                #prime[rev[j]]=0
                m.append('%s!=%i'%(name,value))
                if not options.has_key(name): options[name]=range(Max[name]+1)
                options[name] = [k for k in options[name] if not k==value]
                if not options[name]:
                    valid=False
                    print 'invalid 2'

        print 'minterm:',','.join(sorted(m))
        if not valid: continue

        print 'options:',options.items()
        names  = sorted(options)
        ranges = [options[k] for k in names]

            
        for p in itertools.product( *ranges ):
            p = dict(zip(names,p))
            if p not in primes:
                primes.append( p )
            

    for p in primes:
        print p
        
    return primes
















        
        options   = {} #dict([(name,range(Max[name]+1)) for name in Equation.variables()])
        valid = True
        m = []
        for j in xrange(len(rev)):
            name, value = rev[j].split('=')
            value = int(value)
            
            if minterm[0] & 1<<j:# non-negated literal
                #prime[rev[j]]=1
                m.append('%s==%i'%(name,value))
                if options.has_key(name):# invalid prime
                    if not value in options[name]:
                        valid=False
                options[name]=[value]
                
            elif not minterm[1] & 1<<j:# negated literal
                #prime[rev[j]]=0
                m.append('%s!=%i'%(name,value))
                if not options.has_key(name): options[name]=range(Max[name]+1)
                options[name] = [k for k in options[name] if not k==value]

        print ','.join(sorted(m))
        if not valid: continue
        
        names  = sorted(options)
        ranges = [options[k] for k in names]

        
        if i==5:
            for k in options:
                print k,options[k]
            
        for p in itertools.product( *ranges ):
            p = dict(zip(names,p))
            if p not in primes:
                primes.append( p )