@@ -0,0 +1,2772 @@
+%22%22%22Support for drudge scripts.%22%22%22%0A%0Aimport collections%0A%0Afrom sympy import Symbol, Indexed, IndexedBase%0A%0A%0A#%0A# Special classes for SymPy objects%0A# ---------------------------------%0A#%0A%0Aclass DrsSymbol(Symbol):%0A    %22%22%22Symbols used in drudge scripts.%0A%0A    The drudge symbol needs to behave as similar to the actual symbol as%0A    possible, because it is possible that they are used for keys in%0A    dictionaries.%0A    %22%22%22%0A%0A    __slots__ = %5B%0A        '_drudge',%0A        '_orig'%0A    %5D%0A%0A    def __new__(cls, drudge, name):%0A        %22%22%22Create a symbol object.%22%22%22%0A        symb = super().__new__(cls, name)%0A        return symb%0A%0A    def __init__(self, drudge, name):%0A        %22%22%22Initialize the symbol object.%22%22%22%0A        self._drudge = drudge%0A        self._orig = Symbol(name)%0A%0A    def __eq__(self, other):%0A        %22%22%22Make equality comparison.%22%22%22%0A        return self._orig == other%0A%0A    def __hash__(self):%0A        %22%22%22Compute the hash.%22%22%22%0A        return hash(self._orig)%0A%0A    def _hashable_content(self):%0A        %22%22%22Hashable content for SymPy usages.%22%22%22%0A        return self._orig._hashable_content()%0A%0A    @classmethod%0A    def class_key(cls):%0A        return Symbol.class_key()%0A%0A    def __getitem__(self, indices):%0A        %22%22%22Index the given symbol.%0A%0A        In drudge scripts, all symbols are by itself indexed bases.%0A        %22%22%22%0A        base = IndexedBase(self._orig)%0A        if isinstance(indices, collections.Sequence):%0A            return DrsIndexed(self._drudge, base, *indices)%0A        else:%0A            return DrsIndexed(self._drudge, base, indices)%0A%0A    def __iter__(self):%0A        %22%22%22Disable iterability of the symbol.%0A%0A        Or a default implementation from %60%60__getitem__%60%60 will be used,%0A        which makes the symbols unable to be used as subscripts for indexed%0A        objects.%0A        %22%22%22%0A        raise TypeError('Drudge script symbol cannot be iterated over.')%0A%0A%0Aclass DrsIndexed(Indexed):%0A    %22%22%22Indexed objects for drudge scripts.%22%22%22%0A%0A    __slots__ = %5B%0A        '_drudge',%0A        '_orig'%0A    %5D%0A%0A    def __new__(cls, drudge, base, *args, **kwargs):%0A        %22%22%22Create an indexed object for drudge scripts.%22%22%22%0A        indexed = super().__new__(cls, base, *args, **kwargs)%0A        return indexed%0A%0A    def __init__(self, drudge, base, *args, **kwargs):%0A        %22%22%22Initialize the indexed object.%22%22%22%0A        self._drudge = drudge%0A        self._orig = Indexed(base, *args, **kwargs)%0A%0A    def __eq__(self, other):%0A        %22%22%22Make equality comparison.%22%22%22%0A        return self._orig == other%0A%0A    def __hash__(self):%0A        %22%22%22Compute the hash.%22%22%22%0A        return hash(self._orig)%0A%0A    def _hashable_content(self):%0A        %22%22%22Hashable content for SymPy usages.%22%22%22%0A        return self._orig._hashable_content()%0A%0A    @classmethod%0A    def class_key(cls):%0A        return Indexed.class_key()%0A

Add utility SymPy subclasses for drudge scripts