Merge branch 'master' of git://repo.or.cz/trinary
[trinary.git] / tools / exprCreator.py
bloba170e8900bea74edb48ca26f3ea0e22a9d8404ef
1 #!env python
2 # vim: set fileencoding=utf8
3 # Created: April 22, 2008
5 # Expression creator
6 # Currently produces list of functions to apply.
7 # Use get_unary to find a unary funcion.
8 # ie. get_unary("ii0")
9 # Use get_dyadic to find a dyadic funcion.
10 # ie. get_dyadic("ii0111001")
11 # Returns: Returns a tuple. True or false (if function was not found)
12 # and a list of functions to apply to get the desired function.
13 # The list is read from left to right.
15 import sys, os
16 import Trits
18 sd = Trits.Trits("ii0") # shift down
19 su = Trits.Trits("011") # shift up
20 s01 = Trits.Trits("i10") # swap 0/1
21 si0 = Trits.Trits("0i1") # swap i/0
22 ru = Trits.Trits("01i") # rotate up
23 rd = Trits.Trits("1i0") # rotate down
24 inv = Trits.Trits("10i") # inverter
26 buf = Trits.Trits("i01") # identity
27 ci = Trits.Trits("iii") # constant i
28 c0 = Trits.Trits("000") # constant 0
29 c1 = Trits.Trits("111") # constant 1
31 valid_chars = ("i", "0", "1")
32 map_t = {False:0, None:1, True:2}
33 map_str = {False:"i", None:"0", True:"1"}
35 basic = {"}":sd, "{":su, ">":s01, "<":si0, "[":ru,
36 "]":rd, "/":inv}
37 easy = {"B":buf, "i":ci, "0":c0, "1":c1}
40 def get_dyadic(desired):
41 ''' get_dyadic: get expression for a dyadic function
42 desired: string representation of desired function
43 returns: Returns a tuple. True or false (if function was not found).
44 A list of expressions for each unary function needed to build
45 the desired function.
46 '''
48 if len(desired) != 9:
49 print "truth table must be 9 chars wide"
50 raise SystemExit
52 for i in range(0, 9):
53 if not desired[i] in valid_chars:
54 print "%s not a valid character" % desired[i]
55 raise SystemExit
57 goal_1 = desired[0:3]
58 goal_2 = desired[3:6]
59 goal_3 = desired[6:9]
61 result_1, gates_1 = get_unary(goal_1)
62 result_2, gates_2 = get_unary(goal_2)
63 result_3, gates_3 = get_unary(goal_3)
65 if result_1 and result_2 and result_3:
66 return True, gates_1, gates_2, gates_3
68 return False, [], [], []
71 def get_unary(desired):
72 ''' get_unary: get expression for a unary function
73 desired: string representation of desired function
74 returns: Returns a tuple. True or false (if function was not found)
75 and a list of functions to apply to get the desired function.
76 The list is read from left to right.
77 '''
79 # do some input error checking
80 if len(desired) != 3:
81 print "truth table must be 3 chars wide"
82 raise SystemExit
84 for i in range(0, 3):
85 if not desired[i] in valid_chars:
86 print "%s not a valid character" % desired[i]
87 raise SystemExit
89 goal = Trits.Trits(desired)
90 crnt = Trits.Trits("i01")
91 l_gates = []
93 for i in easy:
94 if goal.equals(easy[i]):
95 return True, [i]
97 count = 0
98 end_cond = True
99 while end_cond and count < 4:
100 end_cond, l_gates = recurse_unary(crnt, goal, [], count)
101 end_cond = not end_cond
102 count = count + 1
104 return (not end_cond, l_gates)
106 def recurse_unary(crnt, goal, l_gates, depth):
107 ''' recurse_unary: attempt to locate a function sequence that makes the
108 goal function
109 crnt: current function result
110 goal: the desired function result
111 l_gates: list of gates to apply to get to crnt
112 count: the number of gate levels
113 returns: Returns a tuple. True or false (if function was not found)
114 and a list of functions to apply to get the desired function.
115 The list is read from left to right.
118 # check the basic gates for an answer
119 if depth == 0:
120 return test_all(crnt, goal, l_gates)
122 else:
123 # for each basic gate attempt to find the desired function
124 for i in basic:
125 cndt = eval_one(crnt, i)
126 l_gates.append(i)
128 if cndt.equals(goal):
129 return True, l_gates
131 status, gates = recurse_unary(cndt, goal, l_gates, depth - 1)
133 if status:
134 return True, gates
136 l_gates.pop()
138 return (False, [])
140 def test_all(crnt, goal, l_gates):
141 ''' test_all: attempt to find a basic function that fulfills the desired
142 gate.
143 crnt: the current evaluation of the function
144 goal: the desired function result
145 l_gates: list of gates currently applied to crnt
146 returns: true and list of gates if goal is met, else false and []
149 for i in basic:
150 cndt = eval_one(crnt, i)
152 # if desired function is found then return true and the list of gates
153 # to apply
154 if cndt.equals(goal):
155 l_gates.append(i)
156 return True, l_gates
158 return False, []
160 def eval_one(crnt, func):
161 ''' eval_one: the input given in crnt with function 'func'
162 crnt: Trits object as input
163 func: function to apply
164 return: Trist object containing result
167 next = ""
168 for i in range(0, 3):
169 next = next + map_str[basic[func][map_t[crnt[i]]]]
171 return Trits.Trits(next)
173 if __name__ == "__main__":
174 result, gates = get_unary("11i")
175 if result:
176 print gates
178 result, gates1, gates2, gates3 = get_dyadic("i0111000i")
179 if result:
180 print gates1, gates2, gates3
182 print "At prompt '>>' enter unary (010) or dyadic (1010i1ii0)"
183 print "Will return list of unary funtions to sequentially apply to a"
184 print "signal starting from the left."
186 while True:
187 valid = True
188 print ">> ",
189 line = sys.stdin.readline()
190 line = line.strip()
191 print
193 if len(line) == 3 or len(line) == 9:
195 for i in range(0, len(line)):
196 if not line[i] in valid_chars:
197 valid = False
199 if valid:
200 if len(line) == 3:
201 result, gates = get_unary(line)
202 print gates
203 if len(line) == 9:
204 result, gates1, gates2, gates3 = get_dyadic(line)
205 print gates1, gates2, gates3