我正在尝试创建一个程序,它使用sympy来获取一组变量并在这些变量的域上评估符号逻辑表达式。问题是我不能让python在吐出真值表后评估表达式。
以下是代码:
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()
如果我执行以下操作,请输出:
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)])
如果存在某些软件来执行此任务,我真的很想知道它: - )
提前致谢。
答案 0 :(得分:7)
你真的很亲密!获得And(p, q, r)
和真值表之后,您可以使用subs
方法将values
dict推送到表达式中:ie。
yield cond + [eval(expr).subs(values)]
给出
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])
但我认为有一种更简单的方法可以做到这一点。 sympify
函数已经可以从字符串生成表达式:
In [7]: expr = sympify("x & y | z")
In [8]: expr
Out[8]: Or(z, And(x, y))
我们也可以得到变量:
In [9]: expr.free_symbols
Out[9]: set([x, z, y])
加itertools.product
可以生成值(cartes
中的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)]
结合这些,基本上只是使用sympify
来获取表达式并避免eval
,使用内置的笛卡尔积,并添加.subs()
来使用values
字典,我们得到:
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)
给出了
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
这比你的短,但它完全采用你的方法。