6

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)])

このタスクを実行するためのソフトウェアが存在する場合、私はそれについて本当に知りたいです:-)

前もって感謝します。

4

1 に答える 1

9

あなたは本当に近いです!And(p, q, r)真理値表を取得したら、メソッドを使用してdict を式subsにプッシュできます。values

    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])

plusitertools.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

これはあなたのものよりも短いですが、まさにあなたのアプローチを使用しています。

于 2012-09-17T16:10:38.363 に答える