Kronecker delta symbol

    Return :class:`One` (`i` equals `j`)), :class:`Zero` (`i` and `j` are
    non-symbolic an unequal), or a :class:`ScalarValue` wrapping SymPy's
    :class:`~sympy.functions.special.tensor_functions.KroneckerDelta`.

        >>> i, j = IdxSym('i'), IdxSym('j')
        >>> KroneckerDelta(i, i)
        One
        >>> KroneckerDelta(1, 2)
        Zero
        >>> KroneckerDelta(i, j)
        KroneckerDelta(i, j)

    By default, the Kronecker delta is returned in a simplified form, e.g::

        >>> KroneckerDelta((i+1)/2, (j+1)/2)
        KroneckerDelta(i, j)

    This may be suppressed by setting `simplify` to False::

        >>> KroneckerDelta((i+1)/2, (j+1)/2, simplify=False)
        KroneckerDelta(i/2 + 1/2, j/2 + 1/2)

    Raises:
        TypeError: if `i` or `j` is not an integer or sympy expression. There
        is no automatic sympification of `i` and `j`.

def KroneckerDelta(i, j, simplify=True):
    """Kronecker delta symbol

    Return :class:`One` (`i` equals `j`)), :class:`Zero` (`i` and `j` are
    non-symbolic an unequal), or a :class:`ScalarValue` wrapping SymPy's
    :class:`~sympy.functions.special.tensor_functions.KroneckerDelta`.

        >>> i, j = IdxSym('i'), IdxSym('j')
        >>> KroneckerDelta(i, i)
        One
        >>> KroneckerDelta(1, 2)
        Zero
        >>> KroneckerDelta(i, j)
        KroneckerDelta(i, j)

    By default, the Kronecker delta is returned in a simplified form, e.g::

        >>> KroneckerDelta((i+1)/2, (j+1)/2)
        KroneckerDelta(i, j)

    This may be suppressed by setting `simplify` to False::

        >>> KroneckerDelta((i+1)/2, (j+1)/2, simplify=False)
        KroneckerDelta(i/2 + 1/2, j/2 + 1/2)

    Raises:
        TypeError: if `i` or `j` is not an integer or sympy expression. There
        is no automatic sympification of `i` and `j`.
    """
    from qnet.algebra.core.scalar_algebra import ScalarValue, One
    if not isinstance(i, (int, sympy.Basic)):
        raise TypeError(
            "i is not an integer or sympy expression: %s" % type(i))
    if not isinstance(j, (int, sympy.Basic)):
        raise TypeError(
            "j is not an integer or sympy expression: %s" % type(j))
    if i == j:
        return One
    else:
        delta = sympy.KroneckerDelta(i, j)
        if simplify:
            delta = _simplify_delta(delta)
        return ScalarValue.create(delta)