Anderson Green
Anderson Green

Reputation: 31800

Solving constraint satisfaction problems in Sympy

I'm attempting to solve some simple Boolean satisfiability problems in Sympy. Here, I tried to solve a constraint that contains the Or logic operator:

from sympy import *
a,b = symbols("a b")

print(solve(Or(Eq(3, b*2), Eq(3, b*3))))
# In other words: (3 equals b*2) or (3 equals b*3)
# [1,3/2] was the answer that I expected

Surprisingly, this leads to an error instead:

TypeError: unsupported operand type(s) for -: 'Or' and 'int'

I can work around this problem using Piecewise, but this is much more verbose:

from sympy import *
a,b = symbols("a b")
print(solve(Piecewise((Eq(3, b*2),Eq(3, b*2)), (Eq(3, b*3),Eq(3, b*3)))))
#prints [1,3/2], as expected

Unfortunately, this work-around fails when I try to solve for two variables instead of one:

from sympy import *
a,b = symbols("a b")

print(solve([Eq(a,3+b),Piecewise((Eq(b,3),Eq(b,3)), (Eq(b,4),Eq(b,4)))]))
#AttributeError: 'BooleanTrue' object has no attribute 'n'

Is there a more reliable way to solve constraints like this one in Sympy?

Upvotes: 1

Views: 2855

Answers (2)

asmeurer
asmeurer

Reputation: 91470

To expand on zaq's answer, SymPy doesn't recognize logical operators in solve, but you can use the fact that

a*b = 0

is equivalent to

a = 0 OR b = 0

That is, multiply the two equations

solve((3 - 2*b)*(3 - 3*b), b)

As an additional note, if you wanted to use AND instead of OR, you can solve for a system. That is,

solve([eq1, eq2])

is equivalent to solving

eq1 = 0 AND eq2 = 0

Upvotes: 5

user6655984
user6655984

Reputation:

Every equation can be expressed as something being equated to 0. For example, 3-2*b = 0 instead of 3 = 2*b. (In Sympy, you don't even have to write the =0 part, it's assumed.) Then you can simply multiply equations to express the OR logic:

>>> from sympy import *
>>> a,b = symbols("a b")
>>> solve((3-b*2)*(3-b*3))
[1, 3/2]
>>> solve([a-3-b, (3-b*2)*(3-b*3)])
[{b: 1, a: 4}, {b: 3/2, a: 9/2}]

Upvotes: 4

Related Questions