2012-09-17 5 views
6

sympy를 사용하여 변수 집합을 가져 와서 해당 변수의 도메인에서 심볼 논리 표현식을 평가하는 프로그램을 만들려고합니다. 문제는 파이썬이 진리표를 뱉은 후에 표현식을 평가할 수 없다는 것입니다. 일부 소프트웨어는이 작업을 수행하기 위해 존재하는 경우, 내가 정말 좋아하는 것 파이썬에서 sympy를 사용하는 진리표

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

그것에 대해 알고 : 나는 다음을 수행, 여기에 출력의

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

: 여기

코드입니다 :-)

미리 감사드립니다.

답변

7

정말 가깝습니다! 당신이 And(p, q, r)하고 진실 테이블을 가지고 한 후에는 식으로 values DICT를 밀어 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을 피하기 직교 제품에 내장하고 .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 

이 당신보다 짧은 준다, 그러나 사용 당신의 접근 방식.

+0

정말 대단합니다. 정말 고마워요, 완벽하게 작동했습니다! – alvonellos

관련 문제