2012-09-17 29 views
6

Tôi đang cố gắng tạo một chương trình, sử dụng sympy để lấy một tập các biến và đánh giá biểu thức logic biểu tượng trên miền của các biến đó. Vấn đề là tôi không thể nhận được python để đánh giá biểu thức sau khi nó phun ra bảng sự thật.Các bảng chân lý trong python sử dụng sympy

Dưới đây là các mã:

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

Nếu tôi làm như sau, đây là kết quả:

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

Nếu một số phần mềm tồn tại để thực hiện nhiệm vụ này, tôi thực sự muốn biết về nó :-)

Xin cảm ơn trước.

Trả lời

7

Bạn thực sự thân thiết! Một khi bạn đã có And(p, q, r) và bảng sự thật của bạn, bạn có thể sử dụng phương pháp subs để đẩy values dict của bạn vào các biểu hiện: tức là

yield cond + [eval(expr).subs(values)] 

cho

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

Nhưng tôi nghĩ rằng có một cách đơn giản hơn để làm cái này. Chức năng sympify đã làm việc để tạo ra biểu thức từ chuỗi:

In [7]: expr = sympify("x & y | z") 

In [8]: expr 
Out[8]: Or(z, And(x, y)) 

và chúng tôi có thể nhận được các biến quá:

In [9]: expr.free_symbols 
Out[9]: set([x, z, y]) 

cộng itertools.product có thể tạo ra các giá trị (và cartes là một bí danh cho nó trong 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)] 

Kết hợp những thứ này, về cơ bản chỉ sử dụng sympify để tải biểu hiện và tránh eval, bằng cách sử dụng tích hợp trong sản phẩm Descartes, và thêm .subs() để sử dụng từ điển values bạn, chúng tôi nhận được:

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) 

mang đến cho

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 

Đây là ngắn hơn của bạn, nhưng nó sử dụng chính xác cách tiếp cận của bạn.

+0

Bạn thật tuyệt vời. Cảm ơn bạn rất nhiều, điều đó đã làm việc hoàn hảo !!! – alvonellos

Các vấn đề liên quan