【问题标题】:Truth tables in python using sympypython中使用sympy的真值表
【发布时间】:2012-09-17 15:45:10
【问题描述】:

我正在尝试创建一个程序,该程序使用 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)])

如果有一些软件可以执行此任务,我真的很想知道它:-)

提前致谢。

【问题讨论】:

    标签: python symbolic-computation


    【解决方案1】:

    你真的很亲密!一旦你有了And(p, q, r) 和你的真值表,你可以使用subs 方法将你的values dict 推送到表达式中:即

        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
    

    这比你的短,但它完全使用你的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-04
      • 1970-01-01
      • 2014-02-19
      • 2021-09-05
      相关资源
      最近更新 更多