Rights tables in python using sympy

I am trying to create a program that uses sympy to take a set of variables and evaluate a symbolic logical expression over the domain of these variables. The problem is that I cannot get python to evaluate the expression after it splashes out the truth table.

Here is the code:

from sympy import * from sympy.abc import p, q, r def get_vars(): vars = [] print "Please enter the number of variables to use in the equation" numVars = int(raw_input()) print "please enter each of the variables on a newline" for i in xrange(numVars): vars.append(raw_input()) return vars def get_expr(): print "Please enter the expression to use" return str(raw_input()) def convert_to_expr(inputStr): return eval(inputStr) def main(): vars = get_vars() expr = get_expr() print("recieved input: " + str(vars) + " expr " + str(expr)) print "Truth table for " + str(len(vars)) + "variable(s)" for i in enumerate(truth_table(vars, expr)): print i def fixed_table(numvars): """ Generate true/false permutations for the given number of variables. So if numvars=2 Returns (not necessarily in this order): True, True True, False False, False False, True """ if numvars is 1: yield [True] yield [False] else: for i in fixed_table(numvars-1): yield i + [True] yield i + [False] def truth_table(vars, expr): """ Takes an array of variables, vars, and displays a truth table for each possible value combination of vars. """ for cond in fixed_table(len(vars)): values=dict(zip(vars,cond)) yield cond + [eval(expr)] if __name__ == "__main__": main() 

If I do the following, here is the conclusion:

  Please enter the number of variables to use in the equation 3 please enter each of the variables on a newline p q r Please enter the expression to use p&q&r recieved input: ['p', 'q', 'r'] expr p&q&r Truth table for 3variable(s) (0, [True, True, True, And(p, q, r)]) (1, [True, True, False, And(p, q, r)]) (2, [True, False, True, And(p, q, r)]) (3, [True, False, False, And(p, q, r)]) (4, [False, True, True, And(p, q, r)]) (5, [False, True, False, And(p, q, r)]) (6, [False, False, True, And(p, q, r)]) (7, [False, False, False, And(p, q, r)]) 

If any software exists to perform this task, I would really like to know about it :-)

Thanks in advance.

+6
source share
1 answer

You are really near! When you have And(p, q, r) and your truth tables, you can use the subs method to push your values tag to the expression: ie

  yield cond + [eval(expr).subs(values)] 

gives

 p&q&r recieved input: ['p', 'q', 'r'] expr p&q&r Truth table for 3variable(s) (0, [True, True, True, True]) (1, [True, True, False, False]) (2, [True, False, True, False]) (3, [True, False, False, False]) (4, [False, True, True, False]) (5, [False, True, False, False]) (6, [False, False, True, False]) (7, [False, False, False, False]) 

But I think there is an easier way to do this. The sympify function already works to generate expressions from strings:

 In [7]: expr = sympify("x & y | z") In [8]: expr Out[8]: Or(z, And(x, y)) 

and we can also get variables:

 In [9]: expr.free_symbols Out[9]: set([x, z, y]) 

plus itertools.product can generate values ​​(and cartes is an alias for it in sympy ):

 In [12]: cartes([False, True], repeat=3) Out[12]: <itertools.product at 0xa24889c> In [13]: list(cartes([False, True], repeat=3)) Out[13]: [(False, False, False), (False, False, True), (False, True, False), (False, True, True), (True, False, False), (True, False, True), (True, True, False), (True, True, True)] 

Combining them, which mainly use sympify to get the expression and avoid eval , using the built-in Cartesian product and adding .subs() to use your values dictionary, we get:

 def explore(): expr_string = raw_input("Enter an expression: ") expr = sympify(expr_string) variables = sorted(expr.free_symbols) for truth_values in cartes([False, True], repeat=len(variables)): values = dict(zip(variables, truth_values)) print sorted(values.items()), expr.subs(values) 

which gives

 In [22]: explore() Enter an expression: a & (b | c) [(a, False), (b, False), (c, False)] False [(a, False), (b, False), (c, True)] False [(a, False), (b, True), (c, False)] False [(a, False), (b, True), (c, True)] False [(a, True), (b, False), (c, False)] False [(a, True), (b, False), (c, True)] True [(a, True), (b, True), (c, False)] True [(a, True), (b, True), (c, True)] True 

This is less than yours, but it uses exactly your approach.

+7
source

Source: https://habr.com/ru/post/925591/


All Articles