2012-09-17 16 views
6

Bir değişken grubu almak ve bu değişkenlerin etki alanı üzerinde sembolik bir mantık ifadesini değerlendirmek için semiyeyi kullanan bir program oluşturmaya çalışıyorum. Sorun şu ki, doğruluk tablosuna tükendikten sonra ifadeyi değerlendirmek için python alamıyorum. Bazı yazılım bu görevi gerçekleştirmek için varsa, ben gerçekten istiyorum Semptomu kullanarak python'daki gerçek tabloları

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

bunu bilmek: Ben aşağıdakileri yaparsanız, burada çıkış var

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

: Burada

kod :-)

Şimdiden teşekkürler.

cevap

7

Gerçekten yakınsınız! Eğer And(p, q, r) ve doğruluk tabloları var sonra, ifade içine values dicti itmek için subs yöntemi kullanabilirsiniz:

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

verir yani Ama daha basit bir yolu olduğunu düşünüyorum Bunu yap. sympify işlevi zaten dizeleri gelen ifadeleri oluşturmak için çalışır:

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

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

ve biz de değişkenleri alabilirsiniz:

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

artı itertools.product değerleri üretebilir (ve cartessympy bunun için bir diğer adıdır) :

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

temelde sadece almak için sympify kullanıyor olan bu birleştiren ifadesi ve kullanma, eval önlemek Kartezyen üründe dahili ve .subs() ekleyerek values sözlük kullanmak için, elde ederiz:

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 

Bu seninkinden daha kısadır veren, ancak kullandığı tam olarak senin yaklaşımın.

+0

Harikasınız. Çok teşekkür ederim, bu mükemmel çalıştı! – alvonellos

İlgili konular