def _trace_single_line(t):
    "\n    Evaluate the trace of a single gamma matrix line inside a ``TensExpr``.\n\n    Notes\n    =====\n\n    If there are ``DiracSpinorIndex.auto_left`` and ``DiracSpinorIndex.auto_right``\n    indices trace over them; otherwise traces are not implied (explain)\n\n\n    Examples\n    ========\n\n    >>> from sympy.physics.hep.gamma_matrices import GammaMatrix as G,         LorentzIndex, _trace_single_line\n    >>> from sympy.tensor.tensor import tensor_indices, TensorHead\n    >>> p = TensorHead('p', [LorentzIndex])\n    >>> i0,i1,i2,i3,i4,i5 = tensor_indices('i0:6', LorentzIndex)\n    >>> _trace_single_line(G(i0)*G(i1))\n    4*metric(i0, i1)\n    >>> _trace_single_line(G(i0)*p(-i0)*G(i1)*p(-i1)) - 4*p(i0)*p(-i0)\n    0\n\n    "

    def _trace_single_line1(t):
        t = t.sorted_components()
        components = t.components
        ncomps = len(components)
        g = LorentzIndex.metric
        hit = 0
        for i in range(ncomps):
            if (components[i] == GammaMatrix):
                hit = 1
                break
        for j in range((i + hit), ncomps):
            if (components[j] != GammaMatrix):
                break
        else:
            j = ncomps
        numG = (j - i)
        if (numG == 0):
            tcoeff = t.coeff
            return (t.nocoeff if tcoeff else t)
        if ((numG % 2) == 1):
            return TensMul.from_data(S.Zero, [], [], [])
        elif (numG > 4):
            a = t.split()
            ind1 = a[i].get_indices()[0]
            ind2 = a[(i + 1)].get_indices()[0]
            aa = (a[:i] + a[(i + 2):])
            t1 = (tensor_mul(*aa) * g(ind1, ind2))
            t1 = t1.contract_metric(g)
            args = [t1]
            sign = 1
            for k in range((i + 2), j):
                sign = (- sign)
                ind2 = a[k].get_indices()[0]
                aa = ((a[:i] + a[(i + 1):k]) + a[(k + 1):])
                t2 = ((sign * tensor_mul(*aa)) * g(ind1, ind2))
                t2 = t2.contract_metric(g)
                t2 = simplify_gpgp(t2, False)
                args.append(t2)
            t3 = TensAdd(*args)
            t3 = _trace_single_line(t3)
            return t3
        else:
            a = t.split()
            t1 = _gamma_trace1(*a[i:j])
            a2 = (a[:i] + a[j:])
            t2 = tensor_mul(*a2)
            t3 = (t1 * t2)
            if (not t3):
                return t3
            t3 = t3.contract_metric(g)
            return t3
    t = t.expand()
    if isinstance(t, TensAdd):
        a = [(_trace_single_line1(x) * x.coeff) for x in t.args]
        return TensAdd(*a)
    elif isinstance(t, (Tensor, TensMul)):
        r = (t.coeff * _trace_single_line1(t))
        return r
    else:
        return trace(t)
Evaluate the trace of a single gamma matrix line inside a ``TensExpr``.

Notes
=====

If there are ``DiracSpinorIndex.auto_left`` and ``DiracSpinorIndex.auto_right``
indices trace over them; otherwise traces are not implied (explain)


Examples
========

>>> from sympy.physics.hep.gamma_matrices import GammaMatrix as G,         LorentzIndex, _trace_single_line
>>> from sympy.tensor.tensor import tensor_indices, TensorHead
>>> p = TensorHead('p', [LorentzIndex])
>>> i0,i1,i2,i3,i4,i5 = tensor_indices('i0:6', LorentzIndex)
>>> _trace_single_line(G(i0)*G(i1))
4*metric(i0, i1)
>>> _trace_single_line(G(i0)*p(-i0)*G(i1)*p(-i1)) - 4*p(i0)*p(-i0)
0
def _trace_single_line(t):
    "\n    Evaluate the trace of a single gamma matrix line inside a ``TensExpr``.\n\n    Notes\n    =====\n\n    If there are ``DiracSpinorIndex.auto_left`` and ``DiracSpinorIndex.auto_right``\n    indices trace over them; otherwise traces are not implied (explain)\n\n\n    Examples\n    ========\n\n    >>> from sympy.physics.hep.gamma_matrices import GammaMatrix as G,         LorentzIndex, _trace_single_line\n    >>> from sympy.tensor.tensor import tensor_indices, TensorHead\n    >>> p = TensorHead('p', [LorentzIndex])\n    >>> i0,i1,i2,i3,i4,i5 = tensor_indices('i0:6', LorentzIndex)\n    >>> _trace_single_line(G(i0)*G(i1))\n    4*metric(i0, i1)\n    >>> _trace_single_line(G(i0)*p(-i0)*G(i1)*p(-i1)) - 4*p(i0)*p(-i0)\n    0\n\n    "

    def _trace_single_line1(t):
        t = t.sorted_components()
        components = t.components
        ncomps = len(components)
        g = LorentzIndex.metric
        hit = 0
        for i in range(ncomps):
            if (components[i] == GammaMatrix):
                hit = 1
                break
        for j in range((i + hit), ncomps):
            if (components[j] != GammaMatrix):
                break
        else:
            j = ncomps
        numG = (j - i)
        if (numG == 0):
            tcoeff = t.coeff
            return (t.nocoeff if tcoeff else t)
        if ((numG % 2) == 1):
            return TensMul.from_data(S.Zero, [], [], [])
        elif (numG > 4):
            a = t.split()
            ind1 = a[i].get_indices()[0]
            ind2 = a[(i + 1)].get_indices()[0]
            aa = (a[:i] + a[(i + 2):])
            t1 = (tensor_mul(*aa) * g(ind1, ind2))
            t1 = t1.contract_metric(g)
            args = [t1]
            sign = 1
            for k in range((i + 2), j):
                sign = (- sign)
                ind2 = a[k].get_indices()[0]
                aa = ((a[:i] + a[(i + 1):k]) + a[(k + 1):])
                t2 = ((sign * tensor_mul(*aa)) * g(ind1, ind2))
                t2 = t2.contract_metric(g)
                t2 = simplify_gpgp(t2, False)
                args.append(t2)
            t3 = TensAdd(*args)
            t3 = _trace_single_line(t3)
            return t3
        else:
            a = t.split()
            t1 = _gamma_trace1(*a[i:j])
            a2 = (a[:i] + a[j:])
            t2 = tensor_mul(*a2)
            t3 = (t1 * t2)
            if (not t3):
                return t3
            t3 = t3.contract_metric(g)
            return t3
    t = t.expand()
    if isinstance(t, TensAdd):
        a = [(_trace_single_line1(x) * x.coeff) for x in t.args]
        return TensAdd(*a)
    elif isinstance(t, (Tensor, TensMul)):
        r = (t.coeff * _trace_single_line1(t))
        return r
    else:
        return trace(t)