Add order details for logic board order.
[trinary.git] / tools / eval.py
blob541dbba920c2e05c36a06867565bf4eeb05b454b
1 #!/usr/bin/python
2 # vim: set fileencoding=utf8
3 # Created: April 5, 2008
4 # By: Antonio Chavez
6 # Extended Trinary Evaluator: Evaluates trinary expression containing unary
7 # and dyadic gates
10 from Expr import *
11 from Trits import *
13 import sys
14 import doctest
15 import traceback
17 dyadic_functions = {
18 u"!" : {False:"i01", None:"001", True:"111"}, # TOR
19 u"@" : {False:"iii", None:"i00", True:"i01"}, # TAND
20 u"#" : {False:"111", None:"100", True:"10i"}, # TNAND
21 u"$" : {False:"10i", None:"00i", True:"111"}, # TNOR
23 # Alternate notation, sometimes easier to type
24 u"+" : {False:"i01", None:"001", True:"111"},
25 u"*" : {False:"iii", None:"i00", True:"i01"},
27 # Grubb's notation
28 u"%" : {False:"i01", None:"001", True:"111"}, # max
29 u"^" : {False:"iii", None:"i00", True:"i01"}, # min
30 u"&" : {False:"i01", None:"0i1", True:"11i"}, # exclusive max
34 def expr_dyadic(expression, variables):
35 ''' This function applies a dyatic function.
36 Recurses down string by calling expr_recurse.
37 '''
38 if not expression[0] in trit_char:
39 first = variables[expression[0]]
40 else:
41 first = expression[0]
43 f_value = trit_bool[first]
45 if len(expression) == 1:
46 return (f_value, "")
48 f_next = expression[1]
50 # found dyatic function. apply the function
51 if f_next in dyadic_functions:
52 f_apply = dyadic_functions[f_next]
53 result, next_expr = expr_recurse(expression[2:], variables)
55 t_func = Trits(f_apply[f_value])
56 t_sec = Trits(trit_string[result])
57 return (evaluate_unary(t_func, t_sec))[0], next_expr
59 # found left paren. apply */AND
60 elif f_next == "(":
61 # first ( something ) => first AND something
63 # apply AND to 'first' variable
64 f_apply = dyadic_functions["*"]
65 t_func = Trits(f_apply[f_value])
67 # grab the expr to apply AND next
68 result, next_expr = expr_recurse(expression[2:], variables)
69 if next_expr[0] != ")":
70 raise ("Expected \")\", found \"%s\"" % (next_expr[0])).encode("utf8")
72 # evaluate: first AND (something)
73 t_sec = Trits(trit_string[result])
74 result = (evaluate_unary(t_func, t_sec))[0]
75 next_expr = next_expr[1:]
77 # evaluate: (first AND something)(AND (next))*
78 while len(next_expr) > 1:
79 t_func = Trits(f_apply[result])
80 result, next_expr = expr_recurse(next_expr, variables)
81 t_sec = Trits(trit_string[result])
82 result = (evaluate_unary(t_func, t_sec))[0]
84 return result, next_expr
86 elif f_next.isalpha():
87 # first * second
89 # grab function to use and grab the name of the second variable
90 f_apply = dyadic_functions["*"]
91 second = variables[f_next]
93 # apply * to 'first' variable and parse second to trit
94 t_func = Trits(f_apply[f_value])
95 t_sec = Trits(trit_string[trit_bool[second]])
97 # apply first * second, return (result, remaining expression string)
98 return (evaluate_unary(t_func, t_sec))[0], expression[2:]
100 else:
101 return (f_value, expression[1:])
103 def expr_unary(expression, variables):
104 count = 0
105 while expression[count] in unary_functions:
106 count = count + 1
108 func = expression[:count]
109 func = func + "a"
111 result, next = expr_recurse(expression[count:], variables)
112 e = Expr(func)
113 return ((e.evaluate(Trits(trit_string[result])))[0], next)
115 def expr_recurse(expression, variables):
116 if expression[0] in unary_functions:
117 return expr_unary(expression, variables)
118 elif expression[0].isalpha():
119 return expr_dyadic(expression, variables)
120 elif expression[0].isdigit():
121 return expr_dyadic(expression, variables)
122 elif expression[0] == "(":
123 expression = expression[1:]
124 result, next = expr_recurse(expression, variables)
125 if next[0] != ")":
126 raise ("Expected \")\", found \"%s\"" % (next[0])).encode("utf8")
128 next = next[1:]
129 f_apply = dyadic_functions["*"]
131 # evaluate: (result)(AND (next))*
132 while len(next) > 1:
133 t_func = Trits(f_apply[result])
134 result, next = expr_recurse(next, variables)
135 t_sec = Trits(trit_string[result])
136 result = (evaluate_unary(t_func, t_sec))[0]
138 return result, next
139 else:
140 raise ("Unexpected character found \"%s\"" % (expression[0])).encode("utf8")
142 def trinary_eval(expression, variables):
143 u'''Evaluates trinary expression. Unary and Dyadic functions supported:
144 Unary: /, ?, ?, ¬, ?, ?, ?, ?, ?, ?
145 Dyadic: see 'dyadic_functions' module global
146 expression: String containing expression to evalutate
147 variables: dictionary of variables and their values
148 returns: The result of evaluating the expression.
150 >>> print trinary_eval("//A+B", {"A" : "i01", "B" : "1"})
152 >>> print trinary_eval("//A+B", {"A" : "1", "B" : "0"})
154 >>> print trinary_eval("//A+B", {"A" : "i", "B" : "0"})
156 >>> print trinary_eval("//A+B", {"A" : "0", "B" : "0"})
158 >>> print trinary_eval("//A+B", {"A" : "0", "B" : "1"})
160 >>> print trinary_eval("/(A+/B*C)",{"A":"0","B":"0","C":"1"})
162 >>> print trinary_eval("A$(/B*C)",{"A":"0","B":"0","C":"1"})
164 >>> print trinary_eval("A$(/B?C)",{"A":"0","B":"0","C":"1"})
168 max_len = 1
169 for i in expression:
170 if i in variables:
171 if len(variables[i]) > max_len:
172 max_len = len(variables[i])
174 if max_len == 1:
175 result, lo = expr_recurse(expression, variables)
176 return trit_string[result]
178 func_vars = {}
179 func_vars["i"] = "i"
180 result = ""
182 for i in range(max_len):
183 for j in expression:
184 if j in variables:
185 if len(variables[j]) > 1:
186 func_vars[j] = variables[j][i]
187 else:
188 func_vars[j] = variables[j]
189 tmp, lo = expr_recurse(expression, func_vars)
190 result += trit_string[tmp]
192 return result
195 if __name__ == "__main__":
196 # self-test
197 doctest.testmod()
199 variables = {}
200 variables["i"] = "i"
202 while True:
203 flag = True
204 print ">> ",
205 line = unicode(sys.stdin.readline(), "utf8")
206 if len(line) == 0:
207 break
208 line = line.strip()
209 print
210 if "=" in line:
211 assignments = line.split(",")
212 for a in assignments:
213 name, value = a.split("=")
215 if name == "i":
216 print "i is reserved, cannot be used as a variable name"
217 else:
218 for k in value:
219 if not k in trit_char:
220 print u"%s, not a valid value" % (k)
221 flag = False
222 if flag:
223 print u"Assigning %s to %s" % (name, value)
224 variables[name] = value
226 elif line == "":
227 for k, v in variables.iteritems():
228 print u"%s: %s" % (k, v)
229 elif line in trit_char:
230 print line
231 else:
232 try:
233 print trinary_eval(line, variables)
234 except:
235 print "An error occured:"
236 traceback.print_exc()