Skip to content

Instantly share code, notes, and snippets.

@SeijiEmery
Last active August 29, 2015 14:06
Show Gist options
  • Save SeijiEmery/addc2c536abe839131fa to your computer and use it in GitHub Desktop.
Save SeijiEmery/addc2c536abe839131fa to your computer and use it in GitHub Desktop.
Truth table generator
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