Re: [sympy] Using sympy.logic to evaluate complex boolean expressions

246 views
Skip to first unread message

Aaron Meurer

unread,
Nov 15, 2012, 5:47:30 AM11/15/12
to sy...@googlegroups.com
Your dictionary m needs to contain the actual symbols themselves, not their string names.  So you need to do m = {0: a, 1:b, ...} (not {0: 'a', 1:'b', ...}).  Alternately, when you call m, wrap the string in Symbol, like Symbol(m[i]) (instead of just a bare m[i]).

Aaron Meurer


On Thu, Nov 15, 2012 at 3:44 AM, faia <lourenc...@gmail.com> wrote:
Hello all,

I'm trying to use sympy.logic.inference, specifically the satisfiable function, to evaluate a large number of boolean expressions automatically.

My rules look something like (b2314 AND b0089) AND (NOT b0089)
I substituted AND, OR and NOT by standard python operators &, | and ~

I also mapped the names of the expression's variables into 'a', 'b', etc for simplicity

a = Symbol('a')
b = Symbol('b')
c = sympy.Symbol('c')
d = sympy.Symbol('d')
e = sympy.Symbol('e')
f = sympy.Symbol('f')
g = sympy.Symbol('g')
h = sympy.Symbol('h')
i = sympy.Symbol('i')
j = sympy.Symbol('j')
k = sympy.Symbol('k')

myrules = []

m={0:'a',1:'b',2:'c',3:'d',4:'e',5:'f',6:'g',7:'h',8:'i',9:'j',10:'k'}

...

bnumber_pattern = re.compile(r"b\d{4}", re.IGNORECASE)
       
        if bnumber_pattern.search(y):
            bnumber_list=bnumber_pattern.findall(y)
            i=0
            for bnumber in bnumber_list: 
               
                print(bnumber)               
                rpl_str=m[i]
                print(rpl_str)
               
                y=y.replace(bnumber,rpl_str)                
                print(y)
               
                i+=1                         
            print(y)   
            print(satisfiable(y))  


So the above rule looks like (a & b) & (~b)

But when running  print(satisfiable(y))
I get an exception: AttributeError: 'str' object has no attribute 'atoms'

I don't know that much of sympy or python to understand what I am doing wrong here.

Could someone help me with this please?

Regards,
Anália

--
You received this message because you are subscribed to the Google Groups "sympy" group.
To view this discussion on the web visit https://groups.google.com/d/msg/sympy/-/yJydX9zSLOEJ.
To post to this group, send email to sy...@googlegroups.com.
To unsubscribe from this group, send email to sympy+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/sympy?hl=en.

Sachin Joglekar

unread,
Nov 15, 2012, 7:51:16 AM11/15/12
to sy...@googlegroups.com
Speaking of logic.inference, is there any way in SymPy to test whether a single statement is a logical consequence of another set of statements?

faia

unread,
Nov 18, 2012, 7:16:35 AM11/18/12
to sy...@googlegroups.com
Hello Aaron,

I tried both your suggestions but it stil doesn't work.

I even simplified the code and the data to look for the problem. But still, I get the attributeerror: 'str' object has no attribute 'atoms'

Any idea?

I would appreciate any help.

Anália

-----------------------------------------------------------------------------------------------------------------------------------------------------

import sympy
from sympy.core import Symbol
from sympy.logic.inference import satisfiable
import re


a = Symbol('a')
b = Symbol('b')
c = sympy.Symbol('c')
d = sympy.Symbol('d')
e = sympy.Symbol('e')
f = sympy.Symbol('f')
g = sympy.Symbol('g')
h = sympy.Symbol('h')
i = sympy.Symbol('i')
j = sympy.Symbol('j')
k = sympy.Symbol('k')


# open file
file=open ("b.txt","r")

for line in file:
    myrules.append([str(n) for n in line.strip().split('\t')])
           
for pair in myrules:
    try:
        x,y = pair[0],pair[1]       
        print(y)       
        print(satisfiable(y))         
    except IndexError:
        print("A line in the file doesn't have enough entries.")

# Close the file
file.close()

--------------------------------------------------------------------------------------------------------------------
b.txt

x    (a) & b
y    ((a & b) | c | d) & e
z    (a) & b

Ronan Lamy

unread,
Nov 18, 2012, 12:29:27 PM11/18/12
to sy...@googlegroups.com
Le 18/11/2012 12:16, faia a �crit :
> Hello Aaron,
>
> I tried both your suggestions but it stil doesn't work.
>
> I even simplified the code and the data to look for the problem. But
> still, I get the attributeerror: 'str' object has no attribute 'atoms'

That's because you only work with strings. To use sympy functions, you
need to convert your strings to sympy objects at some point.
>
> Any idea?

I'll comment your script in-line.
>
> I would appreciate any help.
>
> An�lia
>
> -----------------------------------------------------------------------------------------------------------------------------------------------------
>
> import sympy
> from sympy.core import Symbol
> from sympy.logic.inference import satisfiable
> import re
>
> a = Symbol('a')
> b = Symbol('b')
> c = sympy.Symbol('c')
> d = sympy.Symbol('d')
> e = sympy.Symbol('e')
> f = sympy.Symbol('f')
> g = sympy.Symbol('g')
> h = sympy.Symbol('h')
> i = sympy.Symbol('i')
> j = sympy.Symbol('j')
> k = sympy.Symbol('k')

You don't use these Python variables, so I think that you don't need these.

>
> # open file
> file=open ("b.txt","r")

(not related to sympy): it's better to open files in a with block, that
way they always get closed automatically at the end of the block.

> for line in file:
> myrules.append([str(n) for n in line.strip().split('\t')])

Here would be a good place to convert the strings into sympy objects.
It could look like this (NB: the with statement replaces both the
file=open(...) and file.close() lines):

myrules = []
with open("b.txt", "r") as file:
for line in file:
myrules.append([sympify(n) for n in line.strip().split('\t')])

>
> for pair in myrules:
> try:
> x,y = pair[0],pair[1]
> print(y)
> print(satisfiable(y))
> except IndexError:
> print("A line in the file doesn't have enough entries.")

With the above change, this should now work.
Reply all
Reply to author
Forward
0 new messages