I created a bit of preliminary code just to play around with this
idea:
--------------------
from sympy.core.basic import Basic, S
from sympy.core.function import Function
class Not(Function):
nargs = 1
@classmethod
def canonize(cls, x):
if x.is_Number:
if x is S.Zero: return S.One
if x is S.One: return S.Zero
raise ValueError('Not: X not in {0, 1}')
return None
class And2(Function):
nargs = 2
@classmethod
def canonize(cls, x, y):
if x.is_Number and y.is_Number:
return x and y
if x.is_Number:
# 1 & Y <=> Y
if x is S.One: return y
# 0 & Y <=> 0
if x is S.Zero: return S.Zero
raise ValueError('And2: X not in {0, 1}')
if y.is_Number:
# X & 1 <=> X
if y is S.One: return x
# X & 0 <=> 0
if y is S.Zero: return S.Zero
raise ValueError('And2: Y not in {0, 1}')
# X & X <=> X
if x is y:
return x
return None
# <clipped Or2 function>
--------------------
I'm looking into the AssocOp code to implement the functions that will
flatten a longer expression, and I have a question. Why does SymPy use
this structure everywhere:
class Basic(...):
is_Atom = False
class AssocOp(...):
@classmethod
def identity(cls):
if cls is Mul: return S.One
These base classes are referencing the type of their sub-classes.
Doesn't this self-referential structure make it difficult to extend
base classes? Every time I add a sub-class, I need to modify the base
class code. For example, maybe it makes sense to add "is_Boolean" to
the Basic class.
I'm not a software engineer. Is there a good reason for this?
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"sympy" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/sympy?hl=en
-~----------~----~----~----~------~----~------~--~---