first commit
This commit is contained in:
205
quine.py
Normal file
205
quine.py
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
from math import ceil
|
||||||
|
from math import log
|
||||||
|
|
||||||
|
def quine(truth, dontcare=None, bits=0):
|
||||||
|
if dontcare is None:
|
||||||
|
dontcare = []
|
||||||
|
|
||||||
|
if bits == 0:
|
||||||
|
bits = int(ceil(log(max(truth + dontcare),2)))
|
||||||
|
|
||||||
|
d = [None] * bits
|
||||||
|
|
||||||
|
getterms = truth + dontcare
|
||||||
|
|
||||||
|
#collect all terms
|
||||||
|
nextcol = [[] for i in range(bits+1)]
|
||||||
|
for item in getterms:
|
||||||
|
tmp = item
|
||||||
|
tru = ['0'] * bits
|
||||||
|
for i in range(bits-1, -1, -1):
|
||||||
|
if tmp >= 2**i:
|
||||||
|
tmp -= 2**i
|
||||||
|
tru[i] = '1'
|
||||||
|
asterm = term(tru)
|
||||||
|
nextcol[asterm.group] += [asterm]
|
||||||
|
|
||||||
|
d[0] = nextcol
|
||||||
|
|
||||||
|
#print(d)
|
||||||
|
#return d
|
||||||
|
|
||||||
|
for col in range(bits-1):
|
||||||
|
nextcol = [[] for i in range(bits-col+1)]
|
||||||
|
for group in range(bits-col):
|
||||||
|
for item1 in d[col][group]:
|
||||||
|
for item2 in d[col][group+1]:
|
||||||
|
if item1.match(item2):
|
||||||
|
asterm = item1.merge(item2)
|
||||||
|
item1.prime = False
|
||||||
|
item2.prime = False
|
||||||
|
if asterm not in nextcol[group]:
|
||||||
|
nextcol[group] += [asterm]
|
||||||
|
|
||||||
|
d[col+1] = nextcol
|
||||||
|
return d
|
||||||
|
|
||||||
|
pimp = term.allprime(d)
|
||||||
|
#return pimp
|
||||||
|
defdict = {}
|
||||||
|
for i in truth:
|
||||||
|
defdict[i] = False
|
||||||
|
ptable = [None] * len(pimp)
|
||||||
|
#return ptable
|
||||||
|
for i in range(len(pimp)):
|
||||||
|
ptable[i] = defdict.copy()
|
||||||
|
for min in truth:
|
||||||
|
ptable[i][min] = min in pimp[i].mins
|
||||||
|
#return ptable
|
||||||
|
prevess = []
|
||||||
|
ess = []
|
||||||
|
covered = set([])
|
||||||
|
while True:
|
||||||
|
for min in [x for x in truth if x not in covered]:
|
||||||
|
terms = []
|
||||||
|
for i in range(len(ptable)):
|
||||||
|
if ptable[i][min]:
|
||||||
|
terms += [i]
|
||||||
|
#print(terms)
|
||||||
|
if len(terms) == 1:
|
||||||
|
#print('test')
|
||||||
|
ess += [pimp[terms[0]]]
|
||||||
|
#print(ess)
|
||||||
|
del ptable[terms[0]]
|
||||||
|
del pimp[terms[0]]
|
||||||
|
#print(ess)
|
||||||
|
# for i in ptable:
|
||||||
|
# del i[min]
|
||||||
|
#print(ess)
|
||||||
|
covered.add(min)
|
||||||
|
break
|
||||||
|
if ess == prevess:
|
||||||
|
break
|
||||||
|
prevess = ess
|
||||||
|
|
||||||
|
notcovered = [x for x in truth if x not in covered]
|
||||||
|
|
||||||
|
#for
|
||||||
|
|
||||||
|
return pimp, ess, ptable, covered, notcovered
|
||||||
|
|
||||||
|
def tovhdl(terms):
|
||||||
|
asstr = ''
|
||||||
|
for i in range(len(terms)):
|
||||||
|
asstr += 'T(%d) <= ' % i
|
||||||
|
strt = 0
|
||||||
|
while True:
|
||||||
|
if terms[i].truth[strt] == '1':
|
||||||
|
asstr += chr(65+strt) + ' '
|
||||||
|
break
|
||||||
|
elif terms[i].truth[strt] == '0':
|
||||||
|
asstr += 'not ' + chr(65+strt) + ' '
|
||||||
|
break
|
||||||
|
strt += 1
|
||||||
|
|
||||||
|
for j in range(strt+1,len(terms[i].truth)):
|
||||||
|
if terms[i].truth[j] == 'x':
|
||||||
|
continue
|
||||||
|
asstr += ' and '
|
||||||
|
if terms[i].truth[j] == '0':
|
||||||
|
asstr += 'not '
|
||||||
|
asstr += chr(j+65)
|
||||||
|
asstr += ';\n'
|
||||||
|
return asstr
|
||||||
|
|
||||||
|
|
||||||
|
def getexpansion(terms):
|
||||||
|
asstr = []
|
||||||
|
for term in terms:
|
||||||
|
m = ''
|
||||||
|
for i in range(len(term.truth)):
|
||||||
|
if term.truth[i] == 'x':
|
||||||
|
continue
|
||||||
|
m += chr(65+i)
|
||||||
|
if term.truth[i] == '0':
|
||||||
|
m += "'"
|
||||||
|
asstr.append(m)
|
||||||
|
fstring = ''
|
||||||
|
for i in range(len(terms)-1):
|
||||||
|
fstring += asstr[i] + ' + '
|
||||||
|
fstring += asstr[-1]
|
||||||
|
return fstring
|
||||||
|
|
||||||
|
def petterms():
|
||||||
|
pass
|
||||||
|
|
||||||
|
class term:
|
||||||
|
|
||||||
|
def __init__(self, truth):
|
||||||
|
self.truth = truth
|
||||||
|
self.group = sum([1 if i == '1' else 0 for i in self.truth])
|
||||||
|
|
||||||
|
dc = []
|
||||||
|
num = 0
|
||||||
|
for i in range(len(self.truth)):
|
||||||
|
if self.truth[i] == '1':
|
||||||
|
num += 2**i
|
||||||
|
elif self.truth[i] == 'x':
|
||||||
|
dc += [2**i]
|
||||||
|
vals = [num]
|
||||||
|
for term in dc:
|
||||||
|
vals += [val + term for val in vals]
|
||||||
|
self.mins = vals
|
||||||
|
|
||||||
|
self.prime = True
|
||||||
|
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
return self.truth == other.truth
|
||||||
|
|
||||||
|
def match(self, other):
|
||||||
|
if len(self.truth) != len(other.truth):
|
||||||
|
raise ValueError('truth values must have equal length')
|
||||||
|
|
||||||
|
cnt = 0
|
||||||
|
for i in range(len(self.truth)):
|
||||||
|
if self.truth[i] == 'x' and other.truth[i] == 'x':
|
||||||
|
continue
|
||||||
|
elif self.truth[i] == 'x' or other.truth[i] == 'x':
|
||||||
|
return False
|
||||||
|
elif self.truth[i] != other.truth[i]:
|
||||||
|
cnt += 1
|
||||||
|
return cnt == 1
|
||||||
|
|
||||||
|
#never use without verifying terms match first
|
||||||
|
def merge(self, other):
|
||||||
|
if len(self.truth) != len(other.truth):
|
||||||
|
raise ValueError('truth values must have equal length')
|
||||||
|
|
||||||
|
newtruth = ['0'] * len(self.truth)
|
||||||
|
for i in range(len(self.truth)):
|
||||||
|
if self.truth[i] == other.truth[i] != 'x':
|
||||||
|
newtruth[i] = self.truth[i]
|
||||||
|
else:
|
||||||
|
newtruth[i] = 'x'
|
||||||
|
return term(newtruth)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def allterms(lst):
|
||||||
|
if isinstance(lst, term):
|
||||||
|
return set(lst.mins)
|
||||||
|
else:
|
||||||
|
mins = set()
|
||||||
|
for i in lst:
|
||||||
|
mins.update(set(term.allterms(i)))
|
||||||
|
return mins
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def allprime(lst):
|
||||||
|
if isinstance(lst, term):
|
||||||
|
return [lst] if lst.prime else []
|
||||||
|
else:
|
||||||
|
terms = []
|
||||||
|
for item in lst:
|
||||||
|
terms += term.allprime(item)
|
||||||
|
return terms
|
||||||
Reference in New Issue
Block a user