Last active
August 29, 2015 14:06
-
-
Save SeijiEmery/addc2c536abe839131fa to your computer and use it in GitHub Desktop.
Truth table generator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import re | |
def bperm (n): | |
""" Returns the permutations of n boolean variables """ | |
if n < 1: | |
return [] | |
if n == 1: | |
return [[True], [False]] | |
vals = bperm(n-1) | |
return [ [True] + v for v in vals ] + [ [False] + v for v in vals ] | |
rvar = re.compile('[_a-zA-Z][_a-zA-Z0-9]*') | |
def pythonify (expr): | |
return expr.replace('&', ' and ').replace('|', ' or ').replace('!', 'not ') | |
pythonic_ops = [ 'and', 'or', 'not' ] | |
not_op = lambda var_: var_ not in pythonic_ops | |
repr_tf = lambda b: 'T' if b else 'F' | |
def gen_truth_table (expr): | |
vars_ = sorted(set(filter(not_op, re.findall(rvar, expr)))) | |
if len(vars_) == 0: | |
return '' | |
vp = bperm(len(vars_)) | |
header = '%s | %s'%(' '.join(vars_), expr) | |
expr = pythonify(expr) | |
tbl = [ '%s | %s'%(' '.join(map(repr_tf, vs)), repr_tf(eval(expr, dict(zip(vars_, vs))))) | |
for vs in vp ] | |
return '\n'.join([header] + tbl) | |
def gen_cpp_lookup_table (func_name, expr): | |
vars_ = sorted(set(filter(not_op, re.findall(rvar, expr)))) | |
unpack_vars = lambda packed_vars: lambda idx: packed_vars & (1 << idx) | |
make_dict = lambda packed_vars: dict(zip(vars_, map(unpack_vars(packed_vars), range(len(vars_))))) | |
expr = pythonify(expr) | |
tbl = [ eval(expr, make_dict(i)) for i in range(2 ** len(vars_)) ] | |
cpp_tf = lambda b: 'true' if b else 'false' | |
tf_values = ', '.join(map(cpp_tf, tbl)) | |
mask = hex(2**len(vars_) - 1)) | |
return ''' | |
bool %s (const std::map<std::string, bool> & vars) { | |
static const std::vector<bool> lookup_table = { | |
%s | |
}; | |
unsigned packed_vars = 0, i = 1; | |
for (auto kv : vars) { | |
packed_vars |= (kv.second ? i ? 0); | |
i <<= 1; | |
} | |
return lookup_table[packed_vars & %s]; | |
}'''%(func_name, tf_values, mask) | |
if __name__ == '__main__': | |
print("Type 'quit' or esc to exit.") | |
while True: | |
input_ = raw_input(">> ") | |
if input_ == 'q' or input_ == 'quit' or input_[0] == chr(27): | |
break | |
try: | |
print(gen_truth_table(input_)) | |
print(gen_cpp_lookup_table('__function_name__', input_)) | |
except Exception, e: | |
print(e) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment