__all__ = [
'Expression',
- 'Symbol', 'symbols',
+ 'Symbol', 'symbols', 'Dummy',
'Rational',
]
return self._name
def __hash__(self):
- return hash(self._name)
+ return hash(self.sortkey())
def coefficient(self, symbol):
if not isinstance(symbol, Symbol):
yield 1
def __eq__(self, other):
- return isinstance(other, Symbol) and self.name == other.name
+ return not isinstance(other, Dummy) and isinstance(other, Symbol) \
+ and self.name == other.name
+
+ def asdummy(self):
+ return Dummy(self.name)
@classmethod
def _fromast(cls, node):
return tuple(Symbol(name) for name in names)
+class Dummy(Symbol):
+
+ __slots__ = (
+ '_name',
+ '_index',
+ )
+
+ _count = 0
+
+ def __new__(cls, name=None):
+ if name is None:
+ name = 'Dummy_{}'.format(Dummy._count)
+ self = object().__new__(cls)
+ self._name = name.strip()
+ self._index = Dummy._count
+ Dummy._count += 1
+ return self
+
+ def __hash__(self):
+ return hash(self.sortkey())
+
+ def sortkey(self):
+ return self._name, self._index
+
+ def __eq__(self, other):
+ return isinstance(other, Dummy) and self._index == other._index
+
+
class Rational(Expression):
__slots__ = (