# Path: drudge/term.py
# class ATerms(abc.ABC):
#     """Abstract base class for terms.
# 
#     This abstract class is meant for things that can be interpreted as a local
#     collection of some tensor terms, mostly used for user input of tensor terms.
# 
#     """
# 
#     @property
#     @abc.abstractmethod
#     def terms(self) -> typing.List['Term']:
#         """Get an list for the terms.
#         """
#         pass
# 
#     #
#     # Mathematical operations.
#     #
# 
#     _op_priority = 19.0  # Just less than the full tensor.
# 
#     def __mul__(self, other):
#         """Multiply something on the right."""
# 
#         if is_higher(other, self._op_priority):
#             return NotImplemented
#         return self._mul(self.terms, parse_terms(other))
# 
#     def __rmul__(self, other):
#         """Multiply something on the left."""
# 
#         if is_higher(other, self._op_priority):
#             return NotImplemented
#         return self._mul(parse_terms(other), self.terms)
# 
#     @staticmethod
#     def _mul(left_terms, right_terms):
#         """Multiply the left terms with the right terms.
# 
#         Note that the terms should not have any conflict in dummies.  Actually,
#         by the common scheme in user input by drudge, the terms should normally
#         have no summations at all.  So this function has different semantics
#         than the term multiplication function from the Terms class.
#         """
# 
#         prod_terms = []
#         for i, j in itertools.product(left_terms, right_terms):
#             # A shallow checking on sums, normally we have no sums by design.
#             sums = _cat_sums(i.sums, j.sums)
#             amp = i.amp * j.amp
#             vecs = i.vecs + j.vecs
# 
#             prod_terms.append(Term(sums, amp, vecs))
#             continue
# 
#         return Terms(prod_terms)
# 
#     def __add__(self, other):
#         """Add something on the right."""
# 
#         if is_higher(other, self._op_priority):
#             return NotImplemented
#         return self._add(self.terms, parse_terms(other))
# 
#     def __radd__(self, other):
#         """Add something on the left."""
# 
#         if is_higher(other, self._op_priority):
#             return NotImplemented
#         return self._add(parse_terms(other), self.terms)
# 
#     def __sub__(self, other):
#         """Subtract something on the right."""
# 
#         if is_higher(other, self._op_priority):
#             return NotImplemented
#         other_terms = self._neg_terms(parse_terms(other))
#         return self._add(self.terms, other_terms)
# 
#     def __rsub__(self, other):
#         """Be subtracted from something on the left."""
# 
#         if is_higher(other, self._op_priority):
#             return NotImplemented
#         self_terms = self._neg_terms(parse_terms(self))
#         return self._add(parse_terms(other), self_terms)
# 
#     def __neg__(self):
#         """Negate the terms."""
#         return Terms(self._neg_terms(parse_terms(self)))
# 
#     @staticmethod
#     def _add(left_terms, right_terms):
#         """Add the terms together.
#         """
#         return Terms(itertools.chain(left_terms, right_terms))
# 
#     @staticmethod
#     def _neg_terms(terms: typing.Iterable['Term']):
#         """Negate the given terms.
# 
#         The resulted terms are lazily evaluated.
#         """
#         return (
#             Term(i.sums, i.amp * _NEG_UNITY, i.vecs)
#             for i in terms
#         )
# 
#     def __truediv__(self, other):
#         """Make division with another object."""
#         other = sympify(other)
#         return Terms([
#             i.scale(1 / other) for i in self.terms
#         ])
# 
#     def __rtruediv__(self, other):
#         """Being divided over by other object."""
#         raise NotImplementedError('General tensors cannot inversed')
# 
#     def __or__(self, other):
#         """Compute the commutator with another object.
#         """
#         if is_higher(other, self._op_priority):
#             return NotImplemented
#         return self * other - other * self
# 
#     def __ror__(self, other):
#         """Compute the commutator with another object on the right."""
#         if is_higher(other, self._op_priority):
#             return NotImplemented
#         return other * self - self * other


import argparse
import ast
import collections
import inspect
        import drudge
            import gristmill
        import sympy
        import builtins
from sympy import Symbol, Indexed, IndexedBase
from .term import ATerms
        from .drudge import current_drudge
        from .drudge import current_drudge
    from drudge import Drudge
        """
        base = IndexedBase(self._orig)
        if isinstance(indices, collections.Sequence):
            return DrsIndexed(self._drudge, base, *indices)
        else:
            return DrsIndexed(self._drudge, base, indices)

    def __iter__(self):
        """Disable iterability of the symbol.

        Or a default implementation from ``__getitem__`` will be used,
        which makes the symbols unable to be used as subscripts for indexed
        objects.
        """
        raise TypeError('Drudge script symbol cannot be iterated over.')

    def __call__(self, *args, **kwargs):
        """Make a call to a tensor method."""
        name = self.name

        if len(args) == 0:
            raise NameError('Undefined function', name)
        else:
            target = args[0]
            rest = args[1:]

            err = NameError('Invalid method', name, 'for', str(type(target)))
            if not hasattr(target, name):
                # It is possible that a tensor method is tried to be called on
                # an input.

# Path: drudge/term.py
# class ATerms(abc.ABC):
#     """Abstract base class for terms.
# 
#     This abstract class is meant for things that can be interpreted as a local
#     collection of some tensor terms, mostly used for user input of tensor terms.
# 
#     """
# 
#     @property
#     @abc.abstractmethod
#     def terms(self) -> typing.List['Term']:
#         """Get an list for the terms.
#         """
#         pass
# 
#     #
#     # Mathematical operations.
#     #
# 
#     _op_priority = 19.0  # Just less than the full tensor.
# 
#     def __mul__(self, other):
#         """Multiply something on the right."""
# 
#         if is_higher(other, self._op_priority):
#             return NotImplemented
#         return self._mul(self.terms, parse_terms(other))
# 
#     def __rmul__(self, other):
#         """Multiply something on the left."""
# 
#         if is_higher(other, self._op_priority):
#             return NotImplemented
#         return self._mul(parse_terms(other), self.terms)
# 
#     @staticmethod
#     def _mul(left_terms, right_terms):
#         """Multiply the left terms with the right terms.
# 
#         Note that the terms should not have any conflict in dummies.  Actually,
#         by the common scheme in user input by drudge, the terms should normally
#         have no summations at all.  So this function has different semantics
#         than the term multiplication function from the Terms class.
#         """
# 
#         prod_terms = []
#         for i, j in itertools.product(left_terms, right_terms):
#             # A shallow checking on sums, normally we have no sums by design.
#             sums = _cat_sums(i.sums, j.sums)
#             amp = i.amp * j.amp
#             vecs = i.vecs + j.vecs
# 
#             prod_terms.append(Term(sums, amp, vecs))
#             continue
# 
#         return Terms(prod_terms)
# 
#     def __add__(self, other):
#         """Add something on the right."""
# 
#         if is_higher(other, self._op_priority):
#             return NotImplemented
#         return self._add(self.terms, parse_terms(other))
# 
#     def __radd__(self, other):
#         """Add something on the left."""
# 
#         if is_higher(other, self._op_priority):
#             return NotImplemented
#         return self._add(parse_terms(other), self.terms)
# 
#     def __sub__(self, other):
#         """Subtract something on the right."""
# 
#         if is_higher(other, self._op_priority):
#             return NotImplemented
#         other_terms = self._neg_terms(parse_terms(other))
#         return self._add(self.terms, other_terms)
# 
#     def __rsub__(self, other):
#         """Be subtracted from something on the left."""
# 
#         if is_higher(other, self._op_priority):
#             return NotImplemented
#         self_terms = self._neg_terms(parse_terms(self))
#         return self._add(parse_terms(other), self_terms)
# 
#     def __neg__(self):
#         """Negate the terms."""
#         return Terms(self._neg_terms(parse_terms(self)))
# 
#     @staticmethod
#     def _add(left_terms, right_terms):
#         """Add the terms together.
#         """
#         return Terms(itertools.chain(left_terms, right_terms))
# 
#     @staticmethod
#     def _neg_terms(terms: typing.Iterable['Term']):
#         """Negate the given terms.
# 
#         The resulted terms are lazily evaluated.
#         """
#         return (
#             Term(i.sums, i.amp * _NEG_UNITY, i.vecs)
#             for i in terms
#         )
# 
#     def __truediv__(self, other):
#         """Make division with another object."""
#         other = sympify(other)
#         return Terms([
#             i.scale(1 / other) for i in self.terms
#         ])
# 
#     def __rtruediv__(self, other):
#         """Being divided over by other object."""
#         raise NotImplementedError('General tensors cannot inversed')
# 
#     def __or__(self, other):
#         """Compute the commutator with another object.
#         """
#         if is_higher(other, self._op_priority):
#             return NotImplemented
#         return self * other - other * self
# 
#     def __ror__(self, other):
#         """Compute the commutator with another object on the right."""
#         if is_higher(other, self._op_priority):
#             return NotImplemented
#         return other * self - self * other


# Path: drudge/drs.py
import argparse
import ast
import collections
import inspect
        import drudge
            import gristmill
        import sympy
        import builtins
from sympy import Symbol, Indexed, IndexedBase
from .term import ATerms
        from .drudge import current_drudge
        from .drudge import current_drudge
    from drudge import Drudge

        """
        base = IndexedBase(self._orig)
        if isinstance(indices, collections.Sequence):
            return DrsIndexed(self._drudge, base, *indices)
        else:
            return DrsIndexed(self._drudge, base, indices)

    def __iter__(self):
        """Disable iterability of the symbol.

        Or a default implementation from ``__getitem__`` will be used,
        which makes the symbols unable to be used as subscripts for indexed
        objects.
        """
        raise TypeError('Drudge script symbol cannot be iterated over.')

    def __call__(self, *args, **kwargs):
        """Make a call to a tensor method."""
        name = self.name

        if len(args) == 0:
            raise NameError('Undefined function', name)
        else:
            target = args[0]
            rest = args[1:]

            err = NameError('Invalid method', name, 'for', str(type(target)))
            if not hasattr(target, name):
                # It is possible that a tensor method is tried to be called on
                # an input.

                if isinstance(target, ATerms):