1

Boolean operation of a Boolean variable on a symbol produces TypeError, but the reverse has no problem:

>>> from sympy import *
>>> x = Symbol('x', bool=True)
>>> x ^ True
Not(x)
>>> True ^ x

Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    True ^ x
TypeError: unsupported operand type(s) for ^: 'bool' and 'Symbol'

I can do try-catch:

try :
    print True ^ x
except TypeError:
    print x ^ True

Not(x)

But, for my present task, it is impossible to implement this with try-except as I have to deal with ~200 symbols. How can I achieve this?

hola
  • 930
  • 1
  • 17
  • 35
  • If you have to deal with 200 symbols; I'm hoping you're using a loop. If you are, why can't you use a try-except block? – ThinkChaos Oct 31 '13 at 09:59
  • @plg I am using a `numpy.array`, `S`, with both symbols and Booleans arbitrarily mixed. I have operations like: `S[15] ^ (S[19] & S[72]) ^ S[112]`. Now, without knowing which one is Boolean and which one is symbol, I can not do try-except things, as number of such try-except blocks will grow exponentially. – hola Oct 31 '13 at 10:05
  • 1
    To use a loop you could define a list of tuples: `[(15, 19, 73, 112), ...]` this won't work if its not always the same operations. You could also use a list of expressions `['S[15] ^ (S[19] & S[72]) ^ S[112]', ...]`, and `eval` them inside a try-except. I wouldn't do that unless I have no other solution though. – ThinkChaos Oct 31 '13 at 10:11
  • @plg Still not clear. Can you give me a MWE? – hola Oct 31 '13 at 10:17
  • For futur reference, what's an MWE? – ThinkChaos Oct 31 '13 at 10:29
  • Minimal Working Example :-) Working on your code now. – hola Oct 31 '13 at 11:44

2 Answers2

2

This is a bug, and it has been fixed in the development version of SymPy, and will be fixed in the next version. If you can't use the git version and can't wait, a workaround would be to monkeypatch __rxor__ (and so on) in sympy.logic.boolalg.Boolean to be equal to sympy.logic.boolalg.Boolean.__xor__.

In [1]: from sympy.logic.boolalg import Boolean

In [2]: Boolean.__rxor__ = Boolean.__xor__

In [3]: True ^ x
Out[3]: ¬ x

By the way, Symbol('x', bool=True) does nothing. It adds the assumption x.is_bool to the Symbol, but since that isn't a real assumption that SymPy knows about, it doesn't do anything.

asmeurer
  • 86,894
  • 26
  • 169
  • 240
-1

This is ugly, but it should do what you want:

expressions = [
  r'S[15] ^ (S[19] & S[72]) ^ S[112]',
]

for e in expressions:
  try:
    eval(e) # Do your thing
  except TypeError:
    pass
ThinkChaos
  • 1,803
  • 2
  • 13
  • 21