2012-09-17 1 views
6

sympyを使って変数のセットを取り、それらの変数のドメイン上でシンボリック論理式を評価するプログラムを作成しようとしています。問題は、Pythonが真理値表を吐き出した後で式を評価することができないということです。ここで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)]) 

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

ありがとうございます。

答えて

7

あなたは本当に近いです!あなたがAnd(p, q, r)を持って、あなたの真理値表したら、式にあなたのvalues辞書をプッシュするsubsメソッドを使用することができます。すなわち

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が値を生成することができます(とcartessympyでのエイリアスです) :

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を避けるため、内蔵の直積を使用して、そしてあなたのvalues辞書を使用するように.subs()を追加し、我々が得る:

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 

これはあなたよりも短くなっているが、それは使用を与える

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) 

あなたのアプローチ。

+0

あなたは素晴らしいです。本当にありがとう、それは完璧に働いた! – alvonellos

関連する問題