-
Notifications
You must be signed in to change notification settings - Fork 19
/
qmccluskey.py
148 lines (117 loc) · 4.79 KB
/
qmccluskey.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
from core.qm.qm import QM
import argparse
import sys
from colorclass import Windows
# TODO
# add validation for variables from CLI and GUI
# enable colours on terminal for windows
#still not working
if sys.platform == "win32":
Windows.enable(auto_colors=True)
# used to check if a string can be an integer
def representsInt(s):
# checks if the string s represents an integer
try:
int(s)
return True
except ValueError:
return False
####### read and parse arguments from the command line ########
parser = argparse.ArgumentParser(description='Quine McCluskey Circuit Minimizer')
group = parser.add_mutually_exclusive_group()
group.add_argument('-m', '--minterms', default=None)
group.add_argument('-p', '--sop', default='')
# parser.add_argument('minterms', metavar='m', type=str, nargs='+',
# help='comma seperated list of minterms to be reduced')
parser.add_argument("-d", "--dont_cares", default="", help="comma seperated list of don't cares")
parser.add_argument("-v", "--variables", default='', help="comma seperated list of variables")
parser.add_argument("-s", "--show_steps", default="yes", help="show steps leading to solution")
args = parser.parse_args()
args = parser.parse_args()
minterms = args.minterms.split(',') if args.minterms else []
if args.sop and args.variables:
sop = args.sop.split('+')
variables = args.variables.split(',')
number_list = {}
for num in range(len(variables) ** 2 - 1):
bin_num = str(bin(num)[2:])
while len(bin_num) < len(variables):
bin_num = '0' + bin_num
number_list[bin_num] = num
dic = {}
list_dic = []
for product in sop:
for variable in product:
if ord(variable) in range(65, 123) and product.index(variable) + 1 < len(product) and product[
product.index(variable) + 1] == "'":
dic[variable] = 0
elif ord(variable) in range(65, 123):
dic[variable] = 1
list_dic.append(dic)
dic = {}
result = []
for mt in list_dic:
for num in number_list:
count = 0
for i in range(len(variables)):
if variables[i] in mt and int(num[i]) == mt[variables[i]]:
count += 1
if len(mt) == count:
result.append(number_list[num])
minterms = list(set(result))
# make sure all the values in the values entered for minterms are valid integers
if not minterms:
sys.exit('Error: sum of product values expected for minterms')
for mt in minterms:
# if it is not a whitespace and it is not an integer
if (mt and not representsInt(mt)) or ((mt and representsInt(mt)) and int(mt) < 0):
sys.exit('Error: Integer values expected for minterms')
# make sure all the values in the values entered for dont cares are valid integers
if args.dont_cares:
dcares = args.dont_cares.split(',')
# make sure the don't cares are all integer values
for dc in dcares:
if (dc and not representsInt(dc)) or ((dc and representsInt(dc)) and int(dc) < 0):
sys.exit('Error : Integer values expected for don\'t cares')
# a term cannot be a don't care and a minterm at the same time
if dc in minterms:
sys.exit('Error: A term cannot be a minterm and a don\'t care at the same time')
else:
dcares = []
##################################add validation for variables here ####################
if args.variables:
variables = args.variables.split(',')
# filter out duplicates in the variables entered
# if there were duplicate terms then let the user know
if len(variables) != len(list(set(variables))):
sys.exit("Error: Duplicate terms not allowed for variables")
# make sure the variables entered are enough to represent the expression
# else raise a value error exception and close the program
# check the number of variables needed
# take into consideration the minter's as well
mterms = map(lambda x: int(x), minterms)
dcs = map(lambda x: int(x), dcares)
max_minterm = max(list(mterms) + list(dcs))
max_minterm = bin(max_minterm)[2:]
if len(variables) != len(max_minterm):
sys.exit("Error: Number of variables entered is not enough to represent expression")
else:
variables = []
# make sure show steps is either a yes or a no
if args.show_steps.lower() != 'yes' and args.show_steps.lower() != 'no':
sys.exit('show_steps expects yes or no')
print(minterms)
# simply expression and print solution if necessary
qm = QM(minterms, dcares, variables)
# pis = qm.pis()
# epis = qm.primary_epis()
# sepis = qm.secondary_epis()
sols = qm.minimize()
if args.show_steps == 'yes':
print(qm.procedure)
else:
print('Solution')
print(sols[0])
if len(sols) > 1:
for i in range(1, len(sols)):
print(sols[i])